From: David Kalnischkies Date: Wed, 7 Aug 2013 16:00:07 +0000 (+0200) Subject: specific pins below 1000 cause downgrades X-Git-Tag: 0.9.11~10^2~3 X-Git-Url: https://git.saurik.com/apt.git/commitdiff_plain/1680800209dc85387c4c2da9a1edfcde44f87807 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 --- diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 4ae3b5f87..0a06cc6e3 100644 --- a/apt-pkg/policy.cc +++ b/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 diff --git a/test/integration/test-bug-543966-downgrade-below-1000-pin b/test/integration/test-bug-543966-downgrade-below-1000-pin new file mode 100755 index 000000000..f602bea95 --- /dev/null +++ b/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