parsehdr: Skip broken dependency with bad (non-numerical) epoch and print warning...
authorTomas Mlcoch <tmlcoch@redhat.com>
Fri, 4 Sep 2015 08:12:06 +0000 (10:12 +0200)
committerTomas Mlcoch <tmlcoch@redhat.com>
Fri, 4 Sep 2015 08:12:06 +0000 (10:12 +0200)
Epoch should be always an integer number.
If epoch is undefined, then we expect the epoch to be 0.
If epoch is a string (non-numerical) then it's obviously a bad
dependency and createrepo_c should print a warning and skip
the dep.

We don't want to abort whole generation of repodata and end with error
becuase createrepo_c is used in critical systems which provide software
updates and we don't want to block an update of dozens of packages just
because of one random package that has one broken dep.
Moreover not all deps are always necessary (for example SUGGESTS or ENHANCES, etc.).
Also, the broken package may be a package that is not used by general
audience, for example a devel or debug package and we definitely
don't want to block update because of such package.

See:
https://lists.fedoraproject.org/pipermail/devel/2015-August/213882.html

src/parsehdr.c

index 670b9b9f134cbdc8df203ba785fce1383e734e07..2f6a79e7e1b9c240f7b9d4c87290cb81c2339e6e 100644 (file)
@@ -24,6 +24,7 @@
 #include "parsehdr.h"
 #include "xml_dump.h"
 #include "misc.h"
+#include "cleanup.h"
 
 #if defined(RPMTAG_SUGGESTS) && defined(RPMTAG_ENHANCES) \
     && defined(RPMTAG_RECOMMENDS) && defined(RPMTAG_SUPPLEMENTS)
@@ -377,11 +378,22 @@ cr_package_from_header(Header hdr,
                     }
                 }
 
+                // Parse dep string
+                cr_EVR *evr = cr_str_to_evr(full_version, pkg->chunk);
+                if ((full_version && *full_version) && !evr->epoch) {
+                    // NULL in epoch mean that the epoch was bad (non-numerical)
+                    _cleanup_free_ gchar *pkg_nevra = cr_package_nevra(pkg);
+                    g_warning("Bad epoch in version string \"%s\" for dependency \"%s\" in package \"%s\"",
+                              full_version, filename, pkg_nevra);
+                    g_warning("Skipping this dependency");
+                    g_free(evr);
+                    continue;
+                }
+
                 // Create dynamic dependency object
                 cr_Dependency *dependency = cr_dependency_new();
                 dependency->name = cr_safe_string_chunk_insert(pkg->chunk, filename);
                 dependency->flags = cr_safe_string_chunk_insert(pkg->chunk, flags);
-                cr_EVR *evr = cr_str_to_evr(full_version, pkg->chunk);
                 dependency->epoch = evr->epoch;
                 dependency->version = evr->version;
                 dependency->release = evr->release;