[gnome-software/1237-fedora-rpm-repo-hidden-by-rpm-fusion-repo: 8/8] Misc: Cannot distinguish the same package coming from two repositories




commit cb4a36bf6005d73b95c2219739e5f360a60b6a22
Author: Milan Crha <mcrha redhat com>
Date:   Wed May 5 18:46:12 2021 +0200

    Misc: Cannot distinguish the same package coming from two repositories
    
    The as_utils_build_data_id() does not respect the passed in 'origin'
    and replaces it with 'os' for the packages, but the same application
    can come from two different package repositories, thus replace
    the as_utils_build_data_id() with a new gs_utils_build_unique_id().
    
    Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1237

 lib/gs-app.c                    | 10 ++++-----
 lib/gs-plugin-event.c           | 11 +++++-----
 lib/gs-utils.c                  | 47 +++++++++++++++++++++++++++++++++++++++++
 lib/gs-utils.h                  |  6 ++++++
 plugins/flatpak/gs-flatpak.c    |  2 +-
 plugins/fwupd/gs-plugin-fwupd.c | 10 ++++-----
 src/gs-common.c                 | 10 ++++-----
 7 files changed, 75 insertions(+), 21 deletions(-)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 877ed1008..ef1347cbc 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -335,11 +335,11 @@ gs_app_get_unique_id_unlocked (GsApp *app)
        /* hmm, do what we can */
        if (priv->unique_id == NULL || !priv->unique_id_valid) {
                g_free (priv->unique_id);
-               priv->unique_id = as_utils_build_data_id (priv->scope,
-                                                         priv->bundle_kind,
-                                                         priv->origin,
-                                                         priv->id,
-                                                         priv->branch);
+               priv->unique_id = gs_utils_build_unique_id (priv->scope,
+                                                           priv->bundle_kind,
+                                                           priv->origin,
+                                                           priv->id,
+                                                           priv->branch);
                priv->unique_id_valid = TRUE;
        }
        return priv->unique_id;
diff --git a/lib/gs-plugin-event.c b/lib/gs-plugin-event.c
index 89787626a..1be73e121 100644
--- a/lib/gs-plugin-event.c
+++ b/lib/gs-plugin-event.c
@@ -26,6 +26,7 @@
 
 #include "gs-plugin-private.h"
 #include "gs-plugin-event.h"
+#include "gs-utils.h"
 
 struct _GsPluginEvent
 {
@@ -173,11 +174,11 @@ gs_plugin_event_get_unique_id (GsPluginEvent *event)
                        g_autofree gchar *id = NULL;
                        id = g_strdup_printf ("%s.error",
                                              gs_plugin_error_to_string (event->error->code));
-                       event->unique_id = as_utils_build_data_id (AS_COMPONENT_SCOPE_UNKNOWN,
-                                                                  AS_BUNDLE_KIND_UNKNOWN,
-                                                                  NULL,
-                                                                  id,
-                                                                  NULL);
+                       event->unique_id = gs_utils_build_unique_id (AS_COMPONENT_SCOPE_UNKNOWN,
+                                                                    AS_BUNDLE_KIND_UNKNOWN,
+                                                                    NULL,
+                                                                    id,
+                                                                    NULL);
                }
                return event->unique_id;
        }
diff --git a/lib/gs-utils.c b/lib/gs-utils.c
index 2fbc4184f..a09a2a00c 100644
--- a/lib/gs-utils.c
+++ b/lib/gs-utils.c
@@ -1248,6 +1248,53 @@ gs_utils_unique_id_compat_convert (const gchar *data_id)
                                parts[5]);
 }
 
+static const gchar *
+_fix_data_id_part (const gchar *value)
+{
+       if (!value || !*value)
+               return "*";
+
+       return value;
+}
+
+/**
+ * gs_utils_build_unique_id:
+ * @scope: Scope of the metadata as #AsComponentScope e.g. %AS_COMPONENT_SCOPE_SYSTEM
+ * @bundle_kind: Bundling system providing this data, e.g. 'package' or 'flatpak'
+ * @origin: Origin string, e.g. 'os' or 'gnome-apps-nightly'
+ * @cid: AppStream component ID, e.g. 'org.freedesktop.appstream.cli'
+ * @branch: Branch, e.g. '3-20' or 'master'
+ *
+ * Builds an identifier string unique to the individual dataset using the supplied information.
+ * It's similar to as_utils_build_data_id(), except it respects the @origin for the packages.
+ *
+ * Returns: (transfer full): a unique ID, free with g_free(), when no longer needed.
+ *
+ * Since: 41
+ */
+gchar *
+gs_utils_build_unique_id (AsComponentScope scope,
+                         AsBundleKind bundle_kind,
+                         const gchar *origin,
+                         const gchar *cid,
+                         const gchar *branch)
+{
+       const gchar *scope_str = NULL;
+       const gchar *bundle_str = NULL;
+
+       if (scope != AS_COMPONENT_SCOPE_UNKNOWN)
+               scope_str = as_component_scope_to_string (scope);
+       if (bundle_kind != AS_BUNDLE_KIND_UNKNOWN)
+               bundle_str = as_bundle_kind_to_string (bundle_kind);
+
+       return g_strdup_printf ("%s/%s/%s/%s/%s",
+                               _fix_data_id_part (scope_str),
+                               _fix_data_id_part (bundle_str),
+                               _fix_data_id_part (origin),
+                               _fix_data_id_part (cid),
+                               _fix_data_id_part (branch));
+}
+
 static void
 gs_pixbuf_blur_private (GdkPixbuf *src, GdkPixbuf *dest, guint radius, guint8 *div_kernel_size)
 {
diff --git a/lib/gs-utils.h b/lib/gs-utils.h
index 1d655676e..2a4402999 100644
--- a/lib/gs-utils.h
+++ b/lib/gs-utils.h
@@ -96,6 +96,12 @@ void          gs_utils_set_online_updates_timestamp (GSettings *settings);
 
 gchar          *gs_utils_unique_id_compat_convert      (const gchar    *data_id);
 
+gchar          *gs_utils_build_unique_id       (AsComponentScope scope,
+                                                AsBundleKind bundle_kind,
+                                                const gchar *origin,
+                                                const gchar *cid,
+                                                const gchar *branch);
+
 void            gs_utils_pixbuf_blur           (GdkPixbuf      *src,
                                                 guint          radius,
                                                 guint          iterations);
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index f58085dee..8d73055ee 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -361,7 +361,7 @@ gs_flatpak_create_app (GsFlatpak *self,
        /* Don't add NULL origin apps to the cache. If the app is later set to
         * origin x the cache may return it as a match for origin y since the cache
         * hash table uses as_utils_data_id_equal() as the equal func and a NULL
-        * origin becomes a "*" in as_utils_build_data_id().
+        * origin becomes a "*" in gs_utils_build_unique_id().
         */
        if (origin != NULL)
                gs_plugin_cache_add (self->plugin, NULL, app);
diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c
index be6a93e8b..40156d48e 100644
--- a/plugins/fwupd/gs-plugin-fwupd.c
+++ b/plugins/fwupd/gs-plugin-fwupd.c
@@ -285,11 +285,11 @@ gs_plugin_fwupd_new_app_from_device (GsPlugin *plugin, FwupdDevice *dev)
                return NULL;
 
        /* get from cache */
-       id = as_utils_build_data_id (AS_COMPONENT_SCOPE_SYSTEM,
-                                    AS_BUNDLE_KIND_UNKNOWN,
-                                    NULL, /* origin */
-                                    fwupd_release_get_appstream_id (rel),
-                                    NULL);
+       id = gs_utils_build_unique_id (AS_COMPONENT_SCOPE_SYSTEM,
+                                      AS_BUNDLE_KIND_UNKNOWN,
+                                      NULL, /* origin */
+                                      fwupd_release_get_appstream_id (rel),
+                                      NULL);
        app = gs_plugin_cache_lookup (plugin, id);
        if (app == NULL) {
                app = gs_app_new (id);
diff --git a/src/gs-common.c b/src/gs-common.c
index 59d7d4303..984aaab10 100644
--- a/src/gs-common.c
+++ b/src/gs-common.c
@@ -622,11 +622,11 @@ gs_utils_build_unique_id_kind (AsComponentKind kind, const gchar *id)
 {
        if (as_utils_data_id_valid (id))
                return g_strdup (id);
-       return as_utils_build_data_id (AS_COMPONENT_SCOPE_UNKNOWN,
-                                      AS_BUNDLE_KIND_UNKNOWN,
-                                      NULL,
-                                      id,
-                                      NULL);
+       return gs_utils_build_unique_id (AS_COMPONENT_SCOPE_UNKNOWN,
+                                        AS_BUNDLE_KIND_UNKNOWN,
+                                        NULL,
+                                        id,
+                                        NULL);
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]