diff -Nru aptitude-0.7.3/debian/changelog aptitude-0.7.3/debian/changelog --- aptitude-0.7.3/debian/changelog 2015-10-12 13:16:29.000000000 -0400 +++ aptitude-0.7.3/debian/changelog 2015-12-13 21:50:27.000000000 -0500 @@ -1,3 +1,11 @@ +aptitude (0.7.3-1ubuntu1+bug1507211.0~15.10.0) wily; urgency=medium + + * Cherry-pick upstream commit d6b67ab from 0.7.4 to fix an infinite + loop and crash when determining which packages can be + automatically deleted (#801430). (Closes: LP: #1507211) + + -- Richard Hansen Sun, 13 Dec 2015 21:45:24 -0500 + aptitude (0.7.3-1ubuntu1) wily; urgency=medium * Merge with Debian; remaining changes: diff -Nru aptitude-0.7.3/debian/patches/0001-Fix-for-circular-dependencies-in-internal_mark_delet.patch aptitude-0.7.3/debian/patches/0001-Fix-for-circular-dependencies-in-internal_mark_delet.patch --- aptitude-0.7.3/debian/patches/0001-Fix-for-circular-dependencies-in-internal_mark_delet.patch 1969-12-31 19:00:00.000000000 -0500 +++ aptitude-0.7.3/debian/patches/0001-Fix-for-circular-dependencies-in-internal_mark_delet.patch 2015-12-13 21:56:15.000000000 -0500 @@ -0,0 +1,106 @@ +From d6b67aba318ab83752f10adabf1b0490d2c88b39 Mon Sep 17 00:00:00 2001 +From: "Manuel A. Fernandez Montecelo" +Date: Wed, 14 Oct 2015 23:53:44 +0100 +Subject: [PATCH] Fix for circular dependencies in internal_mark_delete() + (Closes: #801430) + +Under some circumstances, when following reverse dependencies of packages to +be deleted to see if they are automatically installed and unused (so they +can be pro-actively marked for deletion as well), the function calls itself +recursively. In this case, it uses this version with an extra parameter to +detect when packages were already visited, to avoid infinite loops in the +case of circular dependencies (bug #801430). +--- + NEWS | 9 +++++++++ + src/generic/apt/aptcache.cc | 28 ++++++++++++++++++++++++++-- + src/generic/apt/aptcache.h | 15 +++++++++++++++ + 3 files changed, 50 insertions(+), 2 deletions(-) + +--- a/src/generic/apt/aptcache.cc ++++ b/src/generic/apt/aptcache.cc +@@ -1231,6 +1231,15 @@ void aptitudeDepCache::internal_mark_delete(const PkgIterator &Pkg, + bool Purge, + bool unused_delete) + { ++ std::vector unused_already_visited; ++ internal_mark_delete(Pkg, Purge, unused_delete, unused_already_visited); ++} ++ ++void aptitudeDepCache::internal_mark_delete(const PkgIterator &Pkg, ++ bool Purge, ++ bool unused_delete, ++ std::vector& unused_already_visited) ++{ + // honour ::Purge-Unused in the main entry point for removing packages, it + // should catch cases of automatically installed and unused packages not + // purged (#724034 and others) +@@ -1275,6 +1284,21 @@ void aptitudeDepCache::internal_mark_delete(const PkgIterator &Pkg, + if (Pkg.CurrentVer().end()) + return; + ++ // to avoid endless recursion/crashes, check if this package has already been ++ // visited for this purpose (the container has to be empty at the start of ++ // each run) ++ auto it = std::find(unused_already_visited.begin(), unused_already_visited.end(), Pkg->ID); ++ if (it == std::end(unused_already_visited)) ++ { ++ // not previously visited, register ++ unused_already_visited.push_back(Pkg->ID); ++ } ++ else ++ { ++ // already visited ++ return; ++ } ++ + // from now and for the remaining of this function, these are "unused + // deletes", so set variable accordingly + unused_delete = true; +@@ -1326,7 +1350,7 @@ void aptitudeDepCache::internal_mark_delete(const PkgIterator &Pkg, + + // if we reach here, can delete the real package providing the + // dependency +- internal_mark_delete(dep_prv.OwnerPkg(), Purge, unused_delete); ++ internal_mark_delete(dep_prv.OwnerPkg(), Purge, unused_delete, unused_already_visited); + } + + // it was a virtual package -- so stop processing the considered +@@ -1356,7 +1380,7 @@ void aptitudeDepCache::internal_mark_delete(const PkgIterator &Pkg, + continue; + } + +- internal_mark_delete(dep_pkg, Purge, unused_delete); ++ internal_mark_delete(dep_pkg, Purge, unused_delete, unused_already_visited); + } + } + } +diff --git a/src/generic/apt/aptcache.h b/src/generic/apt/aptcache.h +index 51a0990..a7d716c 100644 +--- a/src/generic/apt/aptcache.h ++++ b/src/generic/apt/aptcache.h +@@ -330,7 +330,22 @@ private: + * package's auto flag is set properly. + */ + void internal_mark_install(const PkgIterator &Pkg, bool AutoInst, bool ReInstall); ++ ++ /** Internally marking packages for deletion -- main entry point ++ */ + void internal_mark_delete(const PkgIterator &Pkg, bool Purge, bool unused_delete); ++ /** Internally marking packages for deletion -- recursive ++ * ++ * When following reverse dependencies to see if they are automatically ++ * installed and unused (so they can be pro-actively marked for deletion as ++ * well), the function calls itself recursively. In this case, it uses this ++ * version with an extra parameter to detect when packages were already ++ * visited, to avoid infinite loops in the case of circular dependencies (bug ++ * #801430). ++ */ ++ void internal_mark_delete(const PkgIterator &Pkg, bool Purge, bool unused_delete, ++ std::vector& unused_already_visited); ++ + void internal_mark_keep(const PkgIterator &Pkg, bool Automatic, bool SetHold); + + /** Handle changing package states to take into account the garbage +-- +2.6.4 + diff -Nru aptitude-0.7.3/debian/patches/series aptitude-0.7.3/debian/patches/series --- aptitude-0.7.3/debian/patches/series 2015-10-12 13:15:33.000000000 -0400 +++ aptitude-0.7.3/debian/patches/series 2015-12-13 21:43:19.000000000 -0500 @@ -2,3 +2,4 @@ 03_branding 04_changelog 14_html2text_preferred +0001-Fix-for-circular-dependencies-in-internal_mark_delet.patch