Quellcode durchsuchen

specific pins below 1000 cause downgrades

We start your quest by using the version of a package applying to a
specific pin, but that version could very well be below the current
version, which causes APT to suggest a downgrade even if it is
advertised that it never does this below 1000.

Its of course questionable what use a specific pin on a package has
which has a newer version already installed, but reacting with the
suggestion of a downgrade is really not appropriated (even if its kinda
likely that this is actually the intend the user has – it could just as
well be an outdated pin) and as pinning is complicated enough we should
atleast do what is described in the manpage.

So we look out for the specific pin and if we haven't seen it at the
moment we see the installed version, we ignore the specific pin.

Closes: 543966
David Kalnischkies vor 13 Jahren
Ursprung
Commit
1680800209
2 geänderte Dateien mit 99 neuen und 7 gelöschten Zeilen
  1. 18 7
      apt-pkg/policy.cc
  2. 81 0
      test/integration/test-bug-543966-downgrade-below-1000-pin

+ 18 - 7
apt-pkg/policy.cc

@@ -166,11 +166,15 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
       tracks the default when the default is taken away, and a permanent
       pin that stays at that setting.
     */
+   bool PrefSeen = false;
    for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
    {
       /* Lets see if this version is the installed version */
       bool instVer = (Pkg.CurrentVer() == Ver);
 
+      if (Pref == Ver)
+	 PrefSeen = true;
+
       for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; ++VF)
       {
 	 /* If this is the status file, and the current version is not the
@@ -187,26 +191,33 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
 	 {
 	    Pref = Ver;
 	    Max = Prio;
+	    PrefSeen = true;
 	 }
 	 if (Prio > MaxAlt)
 	 {
 	    PrefAlt = Ver;
 	    MaxAlt = Prio;
-	 }	 
-      }      
-      
+	 }
+      }
+
       if (instVer == true && Max < 1000)
       {
+	 /* Not having seen the Pref yet means we have a specific pin below 1000
+	    on a version below the current installed one, so ignore the specific pin
+	    as this would be a downgrade otherwise */
+	 if (PrefSeen == false || Pref.end() == true)
+	 {
+	    Pref = Ver;
+	    PrefSeen = true;
+	 }
 	 /* Elevate our current selection (or the status file itself)
 	    to the Pseudo-status priority. */
-	 if (Pref.end() == true)
-	    Pref = Ver;
 	 Max = 1000;
-	 
+
 	 // Fast path optimize.
 	 if (StatusOverride == false)
 	    break;
-      }            
+      }
    }
    // If we do not find our candidate, use the one with the highest pin.
    // This means that if there is a version available with pin > 0; there

+ 81 - 0
test/integration/test-bug-543966-downgrade-below-1000-pin

@@ -0,0 +1,81 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture 'i386'
+
+insertpackage 'unstable' 'base-files' 'all' '5.0.0'
+insertinstalledpackage 'base-files' 'all' '5.0.0-1'
+
+setupaptarchive
+
+STATUS=$(readlink -f rootdir/var/lib/dpkg/status)
+APTARCHIVE="$(readlink -f aptarchive)/"
+
+testequal "base-files:
+  Installed: 5.0.0-1
+  Candidate: 5.0.0-1
+  Version table:
+ *** 5.0.0-1 0
+        100 $STATUS
+     5.0.0 0
+        500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=0
+
+echo 'Package: base-files
+Pin: release a=unstable
+Pin-Priority: 99' > rootdir/etc/apt/preferences
+
+testequal "base-files:
+  Installed: 5.0.0-1
+  Candidate: 5.0.0-1
+  Package pin: 5.0.0
+  Version table:
+ *** 5.0.0-1 99
+        100 $STATUS
+     5.0.0 99
+        500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=99
+
+echo 'Package: base-files
+Pin: release a=unstable
+Pin-Priority: 100' > rootdir/etc/apt/preferences
+
+testequal "base-files:
+  Installed: 5.0.0-1
+  Candidate: 5.0.0-1
+  Package pin: 5.0.0
+  Version table:
+ *** 5.0.0-1 100
+        100 $STATUS
+     5.0.0 100
+        500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=100
+
+echo 'Package: base-files
+Pin: release a=unstable
+Pin-Priority: 999' > rootdir/etc/apt/preferences
+
+testequal "base-files:
+  Installed: 5.0.0-1
+  Candidate: 5.0.0-1
+  Package pin: 5.0.0
+  Version table:
+ *** 5.0.0-1 999
+        100 $STATUS
+     5.0.0 999
+        500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=999
+
+echo 'Package: base-files
+Pin: release a=unstable
+Pin-Priority: 1000' > rootdir/etc/apt/preferences
+
+testequal "base-files:
+  Installed: 5.0.0-1
+  Candidate: 5.0.0
+  Package pin: 5.0.0
+  Version table:
+ *** 5.0.0-1 1000
+        100 $STATUS
+     5.0.0 1000
+        500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=1000