From 933370a6b7ae2752c6661d991db0d83e892a43b9 Mon Sep 17 00:00:00 2001 From: Lubos Kardos Date: May 17 2016 14:20:23 +0000 Subject: - Filter unversioned deps if corresponding versioned deps exist - Resolves: #678605 --- diff --git a/rpm-4.13.0-filter-unversioned.patch b/rpm-4.13.0-filter-unversioned.patch new file mode 100644 index 0000000..7f7070d --- /dev/null +++ b/rpm-4.13.0-filter-unversioned.patch @@ -0,0 +1,277 @@ +From 6ac793b215ac8d9db99d9632cbf71b014c7ffee0 Mon Sep 17 00:00:00 2001 +From: Lubos Kardos +Date: Thu, 12 May 2016 16:28:09 +0200 +Subject: [PATCH] Filter unversioned deps if corresponding versioned deps exist + (rhbz:678605) + +After automatic dependencies are generated filter out from them +unversioned dependencies if versioned dependencies with the same name, +type and color already exist. +--- + build/rpmfc.c | 173 +++++++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 118 insertions(+), 55 deletions(-) + +diff --git a/build/rpmfc.c b/build/rpmfc.c +index 73996e8..10fbd68 100644 +--- a/build/rpmfc.c ++++ b/build/rpmfc.c +@@ -34,6 +34,17 @@ typedef struct rpmfcAttr_s { + struct matchRule excl; + } * rpmfcAttr; + ++typedef struct { ++ int fileIx; ++ rpmds dep; ++} rpmfcFileDep; ++ ++typedef struct { ++ rpmfcFileDep *data; ++ int size; ++ int alloced; ++} rpmfcFileDeps; ++ + /** + */ + struct rpmfc_s { +@@ -56,7 +67,7 @@ struct rpmfc_s { + ARGI_t fddictn; /*!< (no. files) file depends dictionary no. entries */ + ARGI_t ddictx; /*!< (no. dependencies) file->dependency mapping */ + rpmstrPool cdict; /*!< file class dictionary */ +- rpmstrPool ddict; /*!< file depends dictionary */ ++ rpmfcFileDeps fileDeps; /*!< file dependency mapping */ + + rpmstrPool pool; /*!< general purpose string storage */ + }; +@@ -398,15 +409,15 @@ static void argvAddUniq(ARGV_t * argvp, const char * key) + + #define hasAttr(_a, _n) (argvSearch((_a), (_n), NULL) != NULL) + +-static void rpmfcAddFileDep(rpmstrPool ddict, int ix, rpmds ds, char deptype) ++static void rpmfcAddFileDep(rpmfcFileDeps *fileDeps, rpmds ds, int ix) + { +- if (ds) { +- char *key = NULL; +- rasprintf(&key, "%08d%c %s %s 0x%08x", ix, deptype, +- rpmdsN(ds), rpmdsEVR(ds), rpmdsFlags(ds)); +- rpmstrPoolId(ddict, key, 1); +- free(key); ++ if (fileDeps->size == fileDeps->alloced) { ++ fileDeps->alloced <<= 2; ++ fileDeps->data = xrealloc(fileDeps->data, ++ fileDeps->alloced * sizeof(fileDeps->data[0])); + } ++ fileDeps->data[fileDeps->size].fileIx = ix; ++ fileDeps->data[fileDeps->size++].dep = ds; + } + + static ARGV_t runCmd(const char *nsdep, const char *depname, +@@ -531,11 +542,9 @@ static int rpmfcHelper(rpmfc fc, int ix, + + /* Add to package and file dependencies unless filtered */ + if (regMatch(exclude, rpmdsDNEVR(ds)+2) == 0) { +- (void) rpmdsMerge(packageDependencies(fc->pkg, tagN), ds); +- rpmfcAddFileDep(fc->ddict, ix, ds, +- tagN == RPMTAG_PROVIDENAME ? 'P' : 'R'); ++ //rpmdsMerge(packageDependencies(fc->pkg, tagN), ds); ++ rpmfcAddFileDep(&fc->fileDeps, ds, ix); + } +- rpmdsFree(ds); + } else { + rpmlog(RPMLOG_ERR, _("invalid dependency (%s): %s\n"), + err, pav[i]); +@@ -745,7 +754,11 @@ rpmfc rpmfcFree(rpmfc fc) + argiFree(fc->fddictn); + argiFree(fc->ddictx); + +- rpmstrPoolFree(fc->ddict); ++ for (int i = 0; i < fc->fileDeps.size; i++) { ++ rpmdsFree(fc->fileDeps.data[i].dep); ++ } ++ free(fc->fileDeps.data); ++ + rpmstrPoolFree(fc->cdict); + + rpmstrPoolFree(fc->pool); +@@ -764,6 +777,9 @@ rpmfc rpmfcCreate(const char *buildRoot, rpmFlags flags) + } + fc->pool = rpmstrPoolCreate(); + fc->pkg = xcalloc(1, sizeof(*fc->pkg)); ++ fc->fileDeps.alloced = 10; ++ fc->fileDeps.data = xmalloc(fc->fileDeps.alloced * ++ sizeof(fc->fileDeps.data[0])); + return fc; + } + +@@ -820,17 +836,82 @@ rpmds rpmfcObsoletes(rpmfc fc) + return rpmfcDependencies(fc, RPMTAG_OBSOLETENAME); + } + ++ ++/* Versioned deps are less than unversioned deps */ ++static int cmpVerDeps(const void *a, const void *b) ++{ ++ rpmfcFileDep *fDepA = (rpmfcFileDep *) a; ++ rpmfcFileDep *fDepB = (rpmfcFileDep *) b; ++ ++ int aIsVersioned = rpmdsFlags(fDepA->dep) & RPMSENSE_SENSEMASK ? 1 : 0; ++ int bIsVersioned = rpmdsFlags(fDepB->dep) & RPMSENSE_SENSEMASK ? 1 : 0; ++ ++ return bIsVersioned - aIsVersioned; ++} ++ ++/* Sort by index */ ++static int cmpIndexDeps(const void *a, const void *b) ++{ ++ rpmfcFileDep *fDepA = (rpmfcFileDep *) a; ++ rpmfcFileDep *fDepB = (rpmfcFileDep *) b; ++ ++ return fDepA->fileIx - fDepB->fileIx; ++} ++ ++/* ++ * Remove unversioned deps if corresponding versioned deps exist but only ++ * if the versioned dependency has the same type and the same color as the versioned. ++ */ ++static void rpmfcNormalizeFDeps(rpmfc fc) ++{ ++ rpmstrPool versionedDeps = rpmstrPoolCreate(); ++ rpmfcFileDep *normalizedFDeps = xmalloc(fc->fileDeps.size * ++ sizeof(normalizedFDeps[0])); ++ int ix = 0; ++ char *depStr; ++ ++ /* Sort. Versioned dependencies first */ ++ qsort(fc->fileDeps.data, fc->fileDeps.size, sizeof(fc->fileDeps.data[0]), ++ cmpVerDeps); ++ ++ for (int i = 0; i < fc->fileDeps.size; i++) { ++ switch (rpmdsTagN(fc->fileDeps.data[i].dep)) { ++ case RPMTAG_REQUIRENAME: ++ case RPMTAG_RECOMMENDNAME: ++ case RPMTAG_SUGGESTNAME: ++ rasprintf(&depStr, "%08x_%c_%s", ++ fc->fcolor[fc->fileDeps.data[i].fileIx], ++ rpmdsD(fc->fileDeps.data[i].dep), ++ rpmdsN(fc->fileDeps.data[i].dep)); ++ ++ if (rpmdsFlags(fc->fileDeps.data[i].dep) & RPMSENSE_SENSEMASK) { ++ /* preserve versioned require dependency */ ++ normalizedFDeps[ix++] = fc->fileDeps.data[i]; ++ rpmstrPoolId(versionedDeps, depStr, 1); ++ } else if (!rpmstrPoolId(versionedDeps, depStr, 0)) { ++ /* preserve unversioned require dep only if versioned dep doesn't exist */ ++ normalizedFDeps[ix++] =fc-> fileDeps.data[i]; ++ } else { ++ rpmdsFree(fc->fileDeps.data[i].dep); ++ } ++ free(depStr); ++ break; ++ default: ++ /* Preserve all non-require dependencies */ ++ normalizedFDeps[ix++] = fc->fileDeps.data[i]; ++ break; ++ } ++ } ++ rpmstrPoolFree(versionedDeps); ++ ++ free(fc->fileDeps.data); ++ fc->fileDeps.data = normalizedFDeps; ++ fc->fileDeps.size = ix; ++} ++ + static rpmRC rpmfcApplyInternal(rpmfc fc) + { +- const char * s; +- char * se; + rpmds ds, * dsp; +- rpmTagVal tagN; +- const char * N; +- const char * EVR; +- rpmsenseFlags Flags; +- unsigned char deptype; +- int nddict; + int previx; + unsigned int val; + int dix; +@@ -862,45 +943,28 @@ static rpmRC rpmfcApplyInternal(rpmfc fc) + } + } + /* No more additions after this, freeze pool to minimize memory use */ +- rpmstrPoolFreeze(fc->ddict, 0); ++ ++ rpmfcNormalizeFDeps(fc); ++ for (int i = 0; i < fc->fileDeps.size; i++) { ++ ds = fc->fileDeps.data[i].dep; ++ rpmdsMerge(packageDependencies(fc->pkg, rpmdsTagN(ds)), ds); ++ } ++ ++ /* Sort by index */ ++ qsort(fc->fileDeps.data, fc->fileDeps.size, ++ sizeof(fc->fileDeps.data[0]), cmpIndexDeps); + + /* Generate per-file indices into package dependencies. */ +- nddict = rpmstrPoolNumStr(fc->ddict); + previx = -1; +- for (rpmsid id = 1; id <= nddict; id++) { +- s = rpmstrPoolStr(fc->ddict, id); +- +- /* Parse out (file#,deptype,N,EVR,Flags) */ +- ix = strtol(s, &se, 10); +- if ( se == NULL ) { +- rpmlog(RPMLOG_ERR, _("Conversion of %s to long integer failed.\n"), s); +- return RPMRC_FAIL; +- } +- +- deptype = *se++; +- se++; +- N = se; +- while (*se && *se != ' ') +- se++; +- *se++ = '\0'; +- EVR = se; +- while (*se && *se != ' ') +- se++; +- *se++ = '\0'; +- Flags = strtol(se, NULL, 16); +- +- dix = -1; +- +- tagN = rpmdsDToTagN(deptype); +- dsp = packageDependencies(fc->pkg, tagN); +- ds = rpmdsSinglePool(fc->pool, tagN, N, EVR, Flags); ++ for (int i = 0; i < fc->fileDeps.size; i++) { ++ ds = fc->fileDeps.data[i].dep; ++ ix = fc->fileDeps.data[i].fileIx; ++ dsp = packageDependencies(fc->pkg, rpmdsTagN(ds)); + dix = rpmdsFind(*dsp, ds); +- rpmdsFree(ds); +- + if (dix < 0) + continue; + +- val = (deptype << 24) | (dix & 0x00ffffff); ++ val = (rpmdsD(ds) << 24) | (dix & 0x00ffffff); + argiAdd(&fc->ddictx, -1, val); + + if (previx != ix) { +@@ -909,8 +973,8 @@ static rpmRC rpmfcApplyInternal(rpmfc fc) + } + if (fc->fddictn && fc->fddictn->vals) + fc->fddictn->vals[ix]++; +- } + ++ } + return RPMRC_OK; + } + +@@ -968,7 +1032,6 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) + + /* Build (sorted) file class dictionary. */ + fc->cdict = rpmstrPoolCreate(); +- fc->ddict = rpmstrPoolCreate(); + + ms = magic_open(msflags); + if (ms == NULL) { +-- +1.9.3 + diff --git a/rpm.spec b/rpm.spec index 51b1565..26a1428 100644 --- a/rpm.spec +++ b/rpm.spec @@ -29,7 +29,7 @@ Summary: The RPM package management system Name: rpm Version: %{rpmver} -Release: %{?snapver:0.%{snapver}.}33%{?dist} +Release: %{?snapver:0.%{snapver}.}34%{?dist} Group: System Environment/Base Url: http://www.rpm.org/ Source0: http://rpm.org/releases/rpm-4.12.x/%{name}-%{srcver}.tar.bz2 @@ -81,6 +81,7 @@ Patch125: rpm-4.13.0-patch-flags.patch Patch126: rpm-4.13.0-no-backup-if-mismatch.patch Patch127: rpm-4.13.0-rpmtd-out-of-bounds.patch Patch128: rpm-4.13.0-stringFormat-sigsegv.patch +Patch129: rpm-4.13.0-filter-unversioned.patch # These are not yet upstream Patch302: rpm-4.7.1-geode-i686.patch @@ -592,6 +593,9 @@ exit 0 %doc doc/librpm/html/* %changelog +* Tue May 17 2016 Lubos Kardos 4.13.0-0.rc1.34 +- Filter unversioned deps if corresponding versioned deps exist (#678605) + * Mon Apr 25 2016 Lubos Kardos 4.13.0-0.rc1.33 - Fix sigsegv in stringFormat() (#1316903) - Fix reading rpmtd behind its size in formatValue() (#1316896)