Przeglądaj źródła

Fix versioned Replaces to not produce file overwrite errors on downgrades

Change does_replace() to take an additional argument for the old
‘struct pkginfoperfile’, instead of hardcoding oldpigp->installed.
Which we use by passing pkg->available when checking if the current
package has files replaced by files from an already installed package.

Closes: #568566
Guillem Jover 16 lat temu
rodzic
commit
418e1fc01d
2 zmienionych plików z 11 dodań i 7 usunięć
  1. 2 0
      debian/changelog
  2. 9 7
      src/archives.c

+ 2 - 0
debian/changelog

@@ -59,6 +59,8 @@ dpkg (1.15.6.2) UNRELEASED; urgency=low
     filename for source as the file is not yet in place due to the rename
     deferral. Thanks to Colin Watson for the initial patch.
   * Do not output the Package-Type field on udeb.
+  * Fix versioned Replaces to not produce file overwrite errors on downgrades.
+    Closes: #568566
 
   [ Updated dpkg translations ]
   * German (Sven Joachim).

+ 9 - 7
src/archives.c

@@ -218,18 +218,18 @@ static time_t currenttime;
 
 static int
 does_replace(struct pkginfo *newpigp, struct pkginfoperfile *newpifp,
-             struct pkginfo *oldpigp)
+             struct pkginfo *oldpigp, struct pkginfoperfile *oldpifp)
 {
   struct dependency *dep;
   
   debug(dbg_depcon,"does_replace new=%s old=%s (%s)",newpigp->name,
-        oldpigp->name,versiondescribe(&oldpigp->installed.version,
-                                      vdew_always));
+        oldpigp->name, versiondescribe(&oldpifp->version, vdew_always));
   for (dep= newpifp->depends; dep; dep= dep->next) {
     if (dep->type != dep_replaces || dep->list->ed != oldpigp) continue;
     debug(dbg_depcondetail,"does_replace ... found old, version %s",
           versiondescribe(&dep->list->version,vdew_always));
-    if (!versionsatisfied(&oldpigp->installed,dep->list)) continue;
+    if (!versionsatisfied(oldpifp, dep->list))
+      continue;
     debug(dbg_depcon,"does_replace ... yes");
     return true;
   }
@@ -573,10 +573,12 @@ int tarobject(struct TarInfo *ti) {
 	  }
 	}
 
-        if (does_replace(tc->pkg,&tc->pkg->available,otherpkg)) {
+        if (does_replace(tc->pkg, &tc->pkg->available,
+                         otherpkg, &otherpkg->installed)) {
           printf(_("Replacing files in old package %s ...\n"),otherpkg->name);
           otherpkg->clientdata->replacingfilesandsaid= 1;
-	} else if (does_replace(otherpkg,&otherpkg->installed,tc->pkg)) {
+        } else if (does_replace(otherpkg, &otherpkg->installed,
+                                tc->pkg, &tc->pkg->available)) {
 	  printf(_("Replaced by files in installed package %s ...\n"),
 		 otherpkg->name);
           otherpkg->clientdata->replacingfilesandsaid= 2;
@@ -992,7 +994,7 @@ void check_conflict(struct dependency *dep, struct pkginfo *pkg,
     }
     if (((pkg->available.essential && fixbyrm->installed.essential) ||
          (((fixbyrm->want != want_install && fixbyrm->want != want_hold) ||
-           does_replace(pkg,&pkg->available,fixbyrm)) &&
+           does_replace(pkg, &pkg->available, fixbyrm, &fixbyrm->installed)) &&
           (!fixbyrm->installed.essential || fc_removeessential)))) {
       assert(fixbyrm->clientdata->istobe == itb_normal || fixbyrm->clientdata->istobe == itb_deconfigure);
       fixbyrm->clientdata->istobe= itb_remove;