diff -Nru --exclude '*.po' --exclude '*.pot' --exclude autom4te.cache --exclude 'configure*' apt-0.8.16~exp5ubuntu13.2/apt-pkg/depcache.cc apt-0.8.16~exp5ubuntu13.3/apt-pkg/depcache.cc --- apt-0.8.16~exp5ubuntu13.2/apt-pkg/depcache.cc 2011-08-15 14:51:29.000000000 +0200 +++ apt-0.8.16~exp5ubuntu13.3/apt-pkg/depcache.cc 2012-04-14 00:22:30.000000000 +0200 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -22,6 +23,7 @@ #include #include +#include #include #include #include @@ -936,6 +938,51 @@ // DepCache::MarkInstall - Put the package in the install state /*{{{*/ // --------------------------------------------------------------------- /* */ +struct CompareProviders { + pkgCache::PkgIterator const Pkg; + CompareProviders(pkgCache::DepIterator const &Dep) : Pkg(Dep.TargetPkg()) {}; + //bool operator() (APT::VersionList::iterator const &AV, APT::VersionList::iterator const &BV) + bool operator() (pkgCache::VerIterator const &AV, pkgCache::VerIterator const &BV) + { + pkgCache::PkgIterator const A = AV.ParentPkg(); + pkgCache::PkgIterator const B = BV.ParentPkg(); + // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64 + if (A->Group != B->Group) + { + if (A->Group == Pkg->Group && B->Group != Pkg->Group) + return false; + else if (B->Group == Pkg->Group && A->Group != Pkg->Group) + return true; + } + // we like essentials + if ((A->Flags & pkgCache::Flag::Essential) != (B->Flags & pkgCache::Flag::Essential)) + { + if ((A->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + return false; + else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + return true; + } + // higher priority seems like a good idea + if (AV->Priority != BV->Priority) + return AV->Priority < BV->Priority; + // prefer native architecture + if (strcmp(A.Arch(), B.Arch()) != 0) + { + if (strcmp(A.Arch(), A.Cache()->NativeArch()) == 0) + return false; + else if (strcmp(B.Arch(), B.Cache()->NativeArch()) == 0) + return true; + std::vector archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); a != archs.end(); ++a) + if (*a == A.Arch()) + return false; + else if (*a == B.Arch()) + return true; + } + // unable to decide… + return A->ID < B->ID; + } +}; bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, unsigned long Depth, bool FromUser, bool ForceImportantDeps) @@ -1098,41 +1145,28 @@ /* This bit is for processing the possibilty of an install/upgrade fixing the problem */ - SPtrArray List = Start.AllTargets(); if (Start->Type != Dep::DpkgBreaks && (DepState[Start->ID] & DepCVer) == DepCVer) { - // Right, find the best version to install.. - Version **Cur = List; - PkgIterator P = Start.TargetPkg(); - PkgIterator InstPkg(*Cache,0); - - // See if there are direct matches (at the start of the list) - for (; *Cur != 0 && (*Cur)->ParentPkg == P.Index(); Cur++) + APT::VersionSet verlist; + pkgCache::VerIterator Cand = PkgState[Start.TargetPkg()->ID].CandidateVerIter(*this); + if (Cand.end() == false && VS().CheckDep(Cand.VerStr(), Start->CompareOp, Start.TargetVer()) == true) + verlist.insert(Cand); + for (PrvIterator Prv = Start.TargetPkg().ProvidesList(); Prv.end() != true; ++Prv) { - PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg); - if (PkgState[Pkg->ID].CandidateVer != *Cur) + pkgCache::VerIterator V = Prv.OwnerVer(); + pkgCache::VerIterator Cand = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this); + if (Cand.end() == true || V != Cand || + VS().CheckDep(Cand.VerStr(), Start->CompareOp, Start.TargetVer()) == false) continue; - InstPkg = Pkg; - break; + verlist.insert(Cand); } + CompareProviders comp(Start); + APT::VersionSet::iterator InstVer = std::max_element(verlist.begin(), verlist.end(), comp); - // Select the highest priority providing package - if (InstPkg.end() == true) - { - pkgPrioSortList(*Cache,Cur); - for (; *Cur != 0; Cur++) - { - PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg); - if (PkgState[Pkg->ID].CandidateVer != *Cur) - continue; - InstPkg = Pkg; - break; - } - } - - if (InstPkg.end() == false) + if (InstVer != verlist.end()) { + pkgCache::PkgIterator InstPkg = InstVer.ParentPkg(); if(DebugAutoInstall == true) std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name() << " as " << Start.DepType() << " of " << Pkg.Name() @@ -1150,7 +1184,7 @@ // mark automatic dependency MarkInstall(InstPkg,true,Depth + 1, false, ForceImportantDeps); // Set the autoflag, after MarkInstall because MarkInstall unsets it - if (P->CurrentVer == 0) + if (InstPkg->CurrentVer == 0) PkgState[InstPkg->ID].Flags |= Flag::Auto; } } @@ -1162,6 +1196,7 @@ upgrade the package. */ if (Start.IsNegative() == true) { + SPtrArray List = Start.AllTargets(); for (Version **I = List; *I != 0; I++) { VerIterator Ver(*this,*I); diff -Nru --exclude '*.po' --exclude '*.pot' --exclude autom4te.cache --exclude 'configure*' apt-0.8.16~exp5ubuntu13.2/apt-pkg/pkgcache.h apt-0.8.16~exp5ubuntu13.3/apt-pkg/pkgcache.h --- apt-0.8.16~exp5ubuntu13.2/apt-pkg/pkgcache.h 2011-08-08 14:29:27.000000000 +0200 +++ apt-0.8.16~exp5ubuntu13.3/apt-pkg/pkgcache.h 2012-04-13 21:03:44.000000000 +0200 @@ -200,6 +200,7 @@ inline PkgFileIterator FileEnd(); inline bool MultiArchCache() const { return MultiArchEnabled; }; + inline char const * const NativeArch() const; // Make me a function pkgVersioningSystem *VS; @@ -215,7 +216,6 @@ private: bool MultiArchEnabled; PkgIterator SingleArchFindPkg(const string &Name); - inline char const * const NativeArch() const; }; /*}}}*/ // Header structure /*{{{*/ diff -Nru --exclude '*.po' --exclude '*.pot' --exclude autom4te.cache --exclude 'configure*' apt-0.8.16~exp5ubuntu13.2/debian/changelog apt-0.8.16~exp5ubuntu13.3/debian/changelog --- apt-0.8.16~exp5ubuntu13.2/debian/changelog 2012-03-05 17:28:19.000000000 +0100 +++ apt-0.8.16~exp5ubuntu13.3/debian/changelog 2012-04-13 20:48:05.000000000 +0200 @@ -1,3 +1,11 @@ +apt (0.8.16~exp5ubuntu13.3) oneiric; urgency=low + + * apt-pkg/depcache.cc: + - prefer native providers over foreigns even if the chain is foreign. + (LP: #850264) + + -- Jean-Louis Dupond Fri, 13 Apr 2012 20:46:29 +0200 + apt (0.8.16~exp5ubuntu13.2) oneiric-security; urgency=low * SECURITY UPDATE: trust bypass via stale InRelease file (LP: #947108)