From 346b042ef1f290fcce0d2d90714061fb0972ec09 Mon Sep 17 00:00:00 2001
From: David Kalnischkies <david@kalnischkies.de>
Date: Thu, 6 Feb 2014 00:13:10 +0100
Subject: [PATCH] discard impossible candidates in MarkInstall

If a (Pre-)Depends can't be satisfied there is no point in keeping the
candidate as is as it is impossible to find a solution for it, so we can
just as well reset the candidate to the currently installed version.
We avoid trying to install this impossible candidate later on this way.

Closes: #735967
---
 apt-pkg/depcache.cc                                |  9 ++-
 .../test-bug-735967-lib32-to-i386-unavailable      | 86 ++++++++++++++++++++++
 2 files changed, 93 insertions(+), 2 deletions(-)
 create mode 100755 test/integration/test-bug-735967-lib32-to-i386-unavailable

diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index f9c891c..7e75a6f 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -1134,8 +1134,13 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	    std::clog << OutputInDepth(Depth) << Start << " can't be satisfied!" << std::endl;
 	 if (Start.IsCritical() == false)
 	    continue;
-	 // if the dependency was critical, we can't install it, so remove it again
-	 MarkDelete(Pkg,false,Depth + 1, false);
+	 // if the dependency was critical, we have absolutely no chance to install it,
+	 // so if it wasn't installed remove it again. If it was, discard the candidate
+	 // as the problemresolver will trip over it otherwise trying to install it (#735967)
+	 if (Pkg->CurrentVer == 0)
+	    MarkDelete(Pkg,false,Depth + 1, false);
+	 else
+	    SetCandidateVersion(Pkg.CurrentVer());
 	 return false;
       }
 
diff --git a/test/integration/test-bug-735967-lib32-to-i386-unavailable b/test/integration/test-bug-735967-lib32-to-i386-unavailable
new file mode 100755
index 0000000..4dbe1d2
--- /dev/null
+++ b/test/integration/test-bug-735967-lib32-to-i386-unavailable
@@ -0,0 +1,86 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture 'i386' 'amd64'
+
+insertpackage 'unstable' 'lib32nss-mdns' 'amd64' '0.10-6' 'Depends: libnss-mdns-i386 (= 0.10-6)'
+insertpackage 'unstable' 'libnss-mdns' 'amd64,i386' '0.10-6' 'Multi-Arch: same
+Breaks: lib32nss-mdns (<< 0.10-6)'
+insertpackage 'unstable' 'libnss-mdns-i386' 'i386' '0.10-6' 'Multi-Arch: foreign
+Depends: libnss-mdns'
+
+insertpackage 'unstable' 'foo' 'amd64' '1' 'Depends: libfoo'
+insertpackage 'unstable' 'libfoo' 'amd64' '1' 'Depends: libfoo-bin'
+insertpackage 'unstable' 'libfoo-bin' 'i386' '0.10-6' 'Multi-Arch: foreign'
+
+insertinstalledpackage 'lib32nss-mdns' 'amd64' '0.9-1'
+insertinstalledpackage 'libnss-mdns' 'amd64' '0.9-1'
+
+insertinstalledpackage 'i-make-packages-important' 'all' '1' 'Depends: libnss-mdns'
+
+setupaptarchive --no-update
+
+# make libnss-mdns-i386 unavailable
+configarchitecture 'amd64'
+testsuccess aptget update
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  lib32nss-mdns
+The following packages will be upgraded:
+  libnss-mdns
+1 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
+Remv lib32nss-mdns [0.9-1]
+Inst libnss-mdns [0.9-1] (0.10-6 unstable [amd64])
+Conf libnss-mdns (0.10-6 unstable [amd64])' aptget dist-upgrade -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo : Depends: libfoo but it is not going to be installed
+E: Unable to correct problems, you have held broken packages.' aptget install foo -s
+
+# activate multiarch
+configarchitecture 'amd64' 'i386'
+testsuccess aptget update
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  libnss-mdns:i386 libnss-mdns-i386:i386
+The following packages will be upgraded:
+  lib32nss-mdns libnss-mdns
+2 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst lib32nss-mdns [0.9-1] (0.10-6 unstable [amd64]) []
+Inst libnss-mdns [0.9-1] (0.10-6 unstable [amd64]) []
+Inst libnss-mdns:i386 (0.10-6 unstable [i386]) []
+Inst libnss-mdns-i386:i386 (0.10-6 unstable [i386])
+Conf libnss-mdns:i386 (0.10-6 unstable [i386])
+Conf libnss-mdns (0.10-6 unstable [amd64])
+Conf libnss-mdns-i386:i386 (0.10-6 unstable [i386])
+Conf lib32nss-mdns (0.10-6 unstable [amd64])' aptget dist-upgrade -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  libfoo libfoo-bin:i386
+The following NEW packages will be installed:
+  foo libfoo libfoo-bin:i386
+0 upgraded, 3 newly installed, 0 to remove and 2 not upgraded.
+Inst libfoo-bin:i386 (0.10-6 unstable [i386])
+Inst libfoo (1 unstable [amd64])
+Inst foo (1 unstable [amd64])
+Conf libfoo-bin:i386 (0.10-6 unstable [i386])
+Conf libfoo (1 unstable [amd64])
+Conf foo (1 unstable [amd64])' aptget install foo -s
-- 
1.9.rc1

