[Aptitude-devel] r2986 - in branches/aptitude-0.3/aptitude: . src/generic

Daniel Burrows dburrows@costa.debian.org
Sun, 10 Apr 2005 01:17:33 +0000


Author: dburrows
Date: Sun Apr 10 01:17:30 2005
New Revision: 2986

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h
Log:
Fix an infinite-recursion bug.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Sun Apr 10 01:17:30 2005
@@ -1,5 +1,9 @@
 2005-04-09  Daniel Burrows  <dburrows@debian.org>
 
+	* src/generic/aptitude_resolver.h:
+
+	  Fix an infinite recursion bug in the broken-dep iterator.
+
 	* src/generic/aptitude_resolver.cc, src/generic/aptitude_resolver.h:
 
 	  Fix some multiply-defined functions by making them inline and/or

Modified: branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h	Sun Apr 10 01:17:30 2005
@@ -855,12 +855,23 @@
     class pkgCache::PrvIterator prv;
     bool prv_open;
 
+    /** \return \b true if the given non-end dep is InstBroken. */
+    bool dep_is_inst_broken(const pkgCache::DepIterator &d)
+    {
+      pkgCache::DepIterator d2;
+
+      while(d2->CompareOp & pkgCache::Dep::Or)
+	++d2;
+
+      return ((*apt_cache_file)[d2] & pkgDepCache::DepGInstall)==0;
+    }
+
     // Push forward to the next interesting point.
     void normalize()
     {
       while(!the_dep.end() &&
 	    !the_dep.IsCritical() &&
-	    ((*apt_cache_file)[the_dep] & pkgDepCache::DepGInstall))
+	    dep_is_inst_broken(the_dep))
 	++the_dep;
 
       while(the_dep.end() && !pkg.end())
@@ -877,13 +888,13 @@
 
 	      while(!the_dep.end() &&
 		    !the_dep.IsCritical() &&
-		    ((*apt_cache_file)[the_dep] & pkgDepCache::DepGInstall))
+		    dep_is_inst_broken(the_dep))
 		++the_dep;
 	    }
 	}
 
-      // Now dep is a broken dep or an end dep.  If it is a conflicts,
-      // we might need to push down into Provides...
+      // Now dep is a broken critical dep or an end dep.  If it is a
+      // conflicts, we might need to push down into Provides...
       if(!the_dep.end() && the_dep->Type == pkgCache::Dep::Conflicts)
 	{
 	  // If we aren't in provides, check whether the dep is
@@ -937,11 +948,14 @@
 	      ++prv;
 	    }
 
-	  // Control should never reach this point because if a
-	  // Conflicts is InstBroken, then SOMETHING providing the
-	  // conflicted name should be planned to be installed.
-	  if(prv.end())
-	    normalize();
+	  // if all provides are exhausted, increment the dep and try
+	  // again.  (probably this was only a self-conflict and
+	  // nothing else)
+	  ++the_dep;
+	  normalize();
+	  // hopefully g++ is smart enough to optimize this into a
+	  // tail call.
+	  return;
 	}
     }
   public: