From 413f67451c89d269d3b373cefd4b3a9bb500960e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Correa=20G=C3=B3mez?= Date: Fri, 31 Dec 2021 00:46:38 +0100 Subject: [PATCH 2/5] gs-external-appstream-utils: hash url to allow same basename Component files generated by tools like appstream-generator all have the same basename: Components-$(ARCH).xml.gz In consequence, before this patch, if multiple urls are specified in "external-appstream-urls" and have the same basename, the secondly downloaded file will either override the first one (user installs), or skip the download because a file with the said basename already exits (system-wide installs). Hashing the url and adding the hash to the basename solves this problem. (cherry picked from commit 576d336e4994741e64b9384e7e05748b614cf981) --- lib/gs-external-appstream-utils.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/gs-external-appstream-utils.c b/lib/gs-external-appstream-utils.c index 39d71b29..82c5f700 100644 --- a/lib/gs-external-appstream-utils.c +++ b/lib/gs-external-appstream-utils.c @@ -87,6 +87,7 @@ gs_external_appstream_get_modification_date (const gchar *file_path) static gboolean gs_external_appstream_refresh_sys (GsPlugin *plugin, const gchar *url, + const gchar *basename, guint cache_age, GCancellable *cancellable, GError **error) @@ -96,7 +97,6 @@ gs_external_appstream_refresh_sys (GsPlugin *plugin, guint status_code; gboolean file_written; g_autofree gchar *tmp_file_path = NULL; - g_autofree gchar *file_name = NULL; g_autofree gchar *local_mod_date = NULL; g_autofree gchar *target_file_path = NULL; g_autoptr(GFileIOStream) iostream = NULL; @@ -104,8 +104,7 @@ gs_external_appstream_refresh_sys (GsPlugin *plugin, g_autoptr(SoupMessage) msg = NULL; /* check age */ - file_name = g_path_get_basename (url); - target_file_path = gs_external_appstream_utils_get_file_cache_path (file_name); + target_file_path = gs_external_appstream_utils_get_file_cache_path (basename); if (!gs_external_appstream_check (target_file_path, cache_age)) { g_debug ("skipping updating external appstream file %s: " "cache age is older than file", @@ -145,7 +144,7 @@ gs_external_appstream_refresh_sys (GsPlugin *plugin, /* write the download contents into a file that will be copied into * the system */ tmp_file_path = gs_utils_get_cache_filename ("external-appstream", - file_name, + basename, GS_UTILS_CACHE_FLAG_WRITEABLE | GS_UTILS_CACHE_FLAG_CREATE_DIRECTORY, error); @@ -196,18 +195,17 @@ gs_external_appstream_refresh_sys (GsPlugin *plugin, static gboolean gs_external_appstream_refresh_user (GsPlugin *plugin, const gchar *url, + const gchar *basename, guint cache_age, GCancellable *cancellable, GError **error) { guint file_age; - g_autofree gchar *basename = NULL; g_autofree gchar *fullpath = NULL; g_autoptr(GFile) file = NULL; g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (plugin)); /* check age */ - basename = g_path_get_basename (url); fullpath = g_build_filename (g_get_user_data_dir (), "app-info", "xmls", @@ -236,13 +234,27 @@ gs_external_appstream_refresh_url (GsPlugin *plugin, GCancellable *cancellable, GError **error) { + g_autofree gchar *basename = NULL; + g_autofree gchar *basename_url = g_path_get_basename (url); + /* make sure different uris with same basenames differ */ + g_autofree gchar *hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1, + url, -1); + if (hash == NULL) { + g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, + "Failed to hash url %s", url); + return FALSE; + } + basename = g_strdup_printf ("%s-%s", hash, basename_url); + if (g_settings_get_boolean (settings, "external-appstream-system-wide")) { return gs_external_appstream_refresh_sys (plugin, url, + basename, cache_age, cancellable, error); } - return gs_external_appstream_refresh_user (plugin, url, cache_age, + return gs_external_appstream_refresh_user (plugin, url, basename, + cache_age, cancellable, error); } -- 2.25.1