diff options
author | Phaedrus Leeds <mwleeds@endlessos.org> | 2021-03-09 18:07:44 -0800 |
---|---|---|
committer | Phaedrus Leeds <mwleeds@endlessos.org> | 2021-03-09 20:36:05 -0800 |
commit | 82f06cc8de06a290a303c5fc1c55996b904491d8 (patch) | |
tree | d4f53fa467181924eb68fdf535f5180c62fbd3b4 | |
parent | 8459d52fbca89b98fdf1d4955d34c2ee5ea7fcd6 (diff) | |
download | ostree-82f06cc8de06a290a303c5fc1c55996b904491d8.tar.gz |
Fix translation of file:// URIs into paths
Currently if a file path contains a special character such as '\', and
that character is encoded into a file:// URI that is passed to
ostree_repo_pull_with_options(), the percent encoding will remain in the
path passed to g_file_new() (in the case of backslash %5C) and the pull
will then fail with a file not found error. This is an important edge
case to handle because by default on many Linux distributions a
filesystem with no label is mounted at a path based on its UUID, and
this is then passed to systemd-escape by Flatpak (when
--enable-auto-sideloading was used at compile time) to create a symbolic
link such as this which contains backslashes:
$ ls -l /run/flatpak/sideload-repos/
total 0
lrwxrwxrwx 1 mwleeds mwleeds 55 Mar 9 14:21
'automount-run-media-mwleeds-29419e8f\x2dc680\x2d4e95\x2d9a31\x2d2cc907d421cb'
-> /run/media/mwleeds/29419e8f-c680-4e95-9a31-2cc907d421cb
And Flatpak then passes libostree a file:// URI containing that path, to
implement sideloading (pulling content from the USB drive).
This results in an error like:
Error: While pulling app/org.videolan.VLC/x86_64/stable from remote
flathub:
/run/flatpak/sideload-repos/automount-run-media-mwleeds-29419e8f%5Cx2dc680%5Cx2d4e95%5Cx2d9a31%5Cx2d2cc907d421cb/.ostree/repo:
opendir(/run/flatpak/sideload-repos/automount-run-media-mwleeds-29419e8f%5Cx2dc680%5Cx2d4e95%5Cx2d9a31%5Cx2d2cc907d421cb/.ostree/repo):
No such file or directory
This patch avoids such errors by using libsoup to %-decode sequences
such as %5C and any others that represent printable characters.
Technically a filename could contain unprintable characters like 0x7F
(DEL) but I'm not sure we need to support that.
Bug report by user:
https://community.endlessos.com/t/can-not-install-vlc-from-usb-drive-3-9-3/16353
-rw-r--r-- | src/libostree/ostree-fetcher-uri.c | 8 | ||||
-rw-r--r-- | src/libostree/ostree-fetcher.h | 3 | ||||
-rw-r--r-- | src/libostree/ostree-repo-pull.c | 3 |
3 files changed, 13 insertions, 1 deletions
diff --git a/src/libostree/ostree-fetcher-uri.c b/src/libostree/ostree-fetcher-uri.c index 485ed187..4f327ea9 100644 --- a/src/libostree/ostree-fetcher-uri.c +++ b/src/libostree/ostree-fetcher-uri.c @@ -113,6 +113,14 @@ _ostree_fetcher_uri_get_path (OstreeFetcherURI *uri) } char * +_ostree_fetcher_uri_normalize_file_path (const char *path) +{ + /* %-decode any characters which would have been encoded by g_file_get_uri() + * but would not have been decoded by libsoup due to being reserved */ + return soup_uri_normalize (path, " \"#%;<>?[\\]^`{|}"); +} + +char * _ostree_fetcher_uri_to_string (OstreeFetcherURI *uri) { return soup_uri_to_string ((SoupURI*)uri, FALSE); diff --git a/src/libostree/ostree-fetcher.h b/src/libostree/ostree-fetcher.h index 2065ee54..8e113c69 100644 --- a/src/libostree/ostree-fetcher.h +++ b/src/libostree/ostree-fetcher.h @@ -88,6 +88,9 @@ char * _ostree_fetcher_uri_get_path (OstreeFetcherURI *uri); char * +_ostree_fetcher_uri_normalize_file_path (const char *path); + +char * _ostree_fetcher_uri_to_string (OstreeFetcherURI *uri); GType _ostree_fetcher_get_type (void) G_GNUC_CONST; diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 6c5bffcf..6255bb8c 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -4117,7 +4117,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (g_str_equal (first_scheme, "file") && !pull_data->require_static_deltas) { g_autofree char *path = _ostree_fetcher_uri_get_path (first_uri); - g_autoptr(GFile) remote_repo_path = g_file_new_for_path (path); + const char *normalized_path = _ostree_fetcher_uri_normalize_file_path (path); + g_autoptr(GFile) remote_repo_path = g_file_new_for_path (normalized_path); pull_data->remote_repo_local = ostree_repo_new (remote_repo_path); if (!ostree_repo_open (pull_data->remote_repo_local, cancellable, error)) goto out; |