summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/policy.cc25
-rwxr-xr-xtest/integration/test-bug-543966-downgrade-below-1000-pin81
2 files changed, 99 insertions, 7 deletions
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