summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhaedrus Leeds <mwleeds@endlessos.org>2021-03-09 18:07:44 -0800
committerPhaedrus Leeds <mwleeds@endlessos.org>2021-03-09 20:36:05 -0800
commit82f06cc8de06a290a303c5fc1c55996b904491d8 (patch)
treed4f53fa467181924eb68fdf535f5180c62fbd3b4
parent8459d52fbca89b98fdf1d4955d34c2ee5ea7fcd6 (diff)
downloadostree-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.c8
-rw-r--r--src/libostree/ostree-fetcher.h3
-rw-r--r--src/libostree/ostree-repo-pull.c3
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;