Blob Blame History Raw
From 7013e4e0de5d3f1538475a92b08687924f5e01c2 Mon Sep 17 00:00:00 2001
From: Ernestas Kulik <ekulik@redhat.com>
Date: Wed, 3 Jun 2020 14:49:50 +0200
Subject: [PATCH] daemon: rpm: Use NEVRA instead of ENVRA

libdnf is only able to parse package names in the NEVRA form, leading to
retrace-server bailing when retracing dumps from, say, gedit.

Closes https://github.com/abrt/abrt/issues/1378
Fixes https://github.com/abrt/retrace-server/issues/233
---
 src/daemon/abrt-action-save-package-data.c | 12 +++++------
 src/daemon/rpm.c                           | 25 +++++++++++-----------
 src/daemon/rpm.h                           |  8 +++----
 3 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/src/daemon/abrt-action-save-package-data.c b/src/daemon/abrt-action-save-package-data.c
index 9373c2b1..de926383 100644
--- a/src/daemon/abrt-action-save-package-data.c
+++ b/src/daemon/abrt-action-save-package-data.c
@@ -228,7 +228,7 @@ static bool is_path_blacklisted(const char *path)
     return false;
 }
 
-static struct pkg_envra *get_script_name(const char *cmdline, char **executable, const char *chroot)
+static struct pkg_nevra *get_script_name(const char *cmdline, char **executable, const char *chroot)
 {
 // TODO: we don't verify that python executable is not modified
 // or that python package is properly signed
@@ -237,7 +237,7 @@ static struct pkg_envra *get_script_name(const char *cmdline, char **executable,
      * This will work only if the cmdline contains the whole path.
      * Example: python /usr/bin/system-control-network
      */
-    struct pkg_envra *script_pkg = NULL;
+    struct pkg_nevra *script_pkg = NULL;
     char *script_name = get_argv1_if_full_path(cmdline);
     if (script_name)
     {
@@ -271,7 +271,7 @@ static int SavePackageDescriptionToDebugDump(const char *dump_dir_name, const ch
     char *rootdir = NULL;
     char *package_short_name = NULL;
     char *fingerprint = NULL;
-    struct pkg_envra *pkg_name = NULL;
+    struct pkg_nevra *pkg_name = NULL;
     char *component = NULL;
     char *kernel = NULL;
     int error = 1;
@@ -353,7 +353,7 @@ static int SavePackageDescriptionToDebugDump(const char *dump_dir_name, const ch
     if (g_regex_match_simple(DEFAULT_INTERPRETERS_REGEX, basename, G_REGEX_EXTENDED, /*MatchFlags*/0) ||
         g_list_find_custom(settings_Interpreters, basename, (GCompareFunc)g_strcmp0))
     {
-        struct pkg_envra *script_pkg = get_script_name(cmdline, &executable, chroot);
+        struct pkg_nevra *script_pkg = get_script_name(cmdline, &executable, chroot);
         /* executable may have changed, check it again */
         if (is_path_blacklisted(executable))
         {
@@ -379,7 +379,7 @@ static int SavePackageDescriptionToDebugDump(const char *dump_dir_name, const ch
             goto ret0;
         }
 
-        free_pkg_envra(pkg_name);
+        free_pkg_nevra(pkg_name);
         pkg_name = script_pkg;
     }
 
@@ -460,7 +460,7 @@ skip_interpreter:
     free(executable);
     free(rootdir);
     free(package_short_name);
-    free_pkg_envra(pkg_name);
+    free_pkg_nevra(pkg_name);
     free(component);
     free(fingerprint);
 
diff --git a/src/daemon/rpm.c b/src/daemon/rpm.c
index 07ad227e..d39901a6 100644
--- a/src/daemon/rpm.c
+++ b/src/daemon/rpm.c
@@ -282,7 +282,7 @@ char* rpm_get_component(const char *filename, const char *rootdir_or_NULL)
 
 #ifdef HAVE_LIBRPM
 #define pkg_add_id(name)                                                \
-    static inline int pkg_add_##name(Header header, struct pkg_envra *p) \
+    static inline int pkg_add_##name(Header header, struct pkg_nevra *p) \
     {                                                                   \
         const char *errmsg = NULL;                                      \
         p->p_##name = headerFormat(header, "%{"#name"}", &errmsg);      \
@@ -294,8 +294,8 @@ char* rpm_get_component(const char *filename, const char *rootdir_or_NULL)
         return -1;                                                      \
     }                                                                   \
 
-pkg_add_id(epoch);
 pkg_add_id(name);
+pkg_add_id(epoch);
 pkg_add_id(version);
 pkg_add_id(release);
 pkg_add_id(arch);
@@ -303,14 +303,14 @@ pkg_add_id(vendor);
 #endif
 
 // caller is responsible to free returned value
-struct pkg_envra *rpm_get_package_nvr(const char *filename, const char *rootdir_or_NULL)
+struct pkg_nevra *rpm_get_package_nvr(const char *filename, const char *rootdir_or_NULL)
 {
 #ifdef HAVE_LIBRPM
     rpmts ts;
     rpmdbMatchIterator iter;
     Header header;
 
-    struct pkg_envra *p = NULL;
+    struct pkg_nevra *p = NULL;
 
     if (rpm_query_file(&ts, &iter, &header, filename, rootdir_or_NULL) < 0)
         return NULL;
@@ -320,6 +320,11 @@ struct pkg_envra *rpm_get_package_nvr(const char *filename, const char *rootdir_
 
     p = libreport_xzalloc(sizeof(*p));
     int r;
+
+    r = pkg_add_name(header, p);
+    if (r)
+        goto error;
+
     r = pkg_add_epoch(header, p);
     if (r)
         goto error;
@@ -333,10 +338,6 @@ struct pkg_envra *rpm_get_package_nvr(const char *filename, const char *rootdir_
         p->p_epoch = libreport_xstrdup("0");
     }
 
-    r = pkg_add_name(header, p);
-    if (r)
-        goto error;
-
     r = pkg_add_version(header, p);
     if (r)
         goto error;
@@ -356,14 +357,14 @@ struct pkg_envra *rpm_get_package_nvr(const char *filename, const char *rootdir_
     if (strcmp(p->p_epoch, "0") == 0)
         p->p_nvr = libreport_xasprintf("%s-%s-%s", p->p_name, p->p_version, p->p_release);
     else
-        p->p_nvr = libreport_xasprintf("%s:%s-%s-%s", p->p_epoch, p->p_name, p->p_version, p->p_release);
+        p->p_nvr = libreport_xasprintf("%s-%s:%s-%s", p->p_name, p->p_epoch, p->p_version, p->p_release);
 
     rpmdbFreeIterator(iter);
     rpmtsFree(ts);
     return p;
 
  error:
-    free_pkg_envra(p);
+    free_pkg_nevra(p);
 
     rpmdbFreeIterator(iter);
     rpmtsFree(ts);
@@ -373,14 +374,14 @@ struct pkg_envra *rpm_get_package_nvr(const char *filename, const char *rootdir_
 #endif
 }
 
-void free_pkg_envra(struct pkg_envra *p)
+void free_pkg_nevra(struct pkg_nevra *p)
 {
     if (!p)
         return;
 
     free(p->p_vendor);
-    free(p->p_epoch);
     free(p->p_name);
+    free(p->p_epoch);
     free(p->p_version);
     free(p->p_release);
     free(p->p_arch);
diff --git a/src/daemon/rpm.h b/src/daemon/rpm.h
index 1fd56e8f..90821f81 100644
--- a/src/daemon/rpm.h
+++ b/src/daemon/rpm.h
@@ -26,17 +26,17 @@
 extern "C" {
 #endif
 
-struct pkg_envra {
+struct pkg_nevra {
     char *p_nvr;
-    char *p_epoch;
     char *p_name;
+    char *p_epoch;
     char *p_version;
     char *p_release;
     char *p_arch;
     char *p_vendor;
 };
 
-void free_pkg_envra(struct pkg_envra *p);
+void free_pkg_nevra(struct pkg_nevra *p);
 
 /**
  * Checks if an application is modified by third party.
@@ -85,7 +85,7 @@ char *rpm_get_fingerprint(const char* pkg);
  * @param filename A file name.
  * @return A package name (malloc'ed string)
  */
-struct pkg_envra *rpm_get_package_nvr(const char *filename, const char *rootdir_or_NULL);
+struct pkg_nevra *rpm_get_package_nvr(const char *filename, const char *rootdir_or_NULL);
 /**
  * Finds a main package for given file. This package contains particular
  * file. If the file doesn't belong to any package, empty string is
-- 
2.26.2