瀏覽代碼

add APT::pkgPackageManager::MaxLoopCount to ensure that the
ordering code does not get into a endless loop when it flip-flops
between two states

Michael Vogt 14 年之前
父節點
當前提交
bce4caa307
共有 2 個文件被更改,包括 15 次插入2 次删除
  1. 12 2
      apt-pkg/packagemanager.cc
  2. 3 0
      debian/changelog

+ 12 - 2
apt-pkg/packagemanager.cc

@@ -337,7 +337,10 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
       however if there is a loop (A depends on B, B depends on A) this will not 
       however if there is a loop (A depends on B, B depends on A) this will not 
       be the case, so check for dependencies before configuring. */
       be the case, so check for dependencies before configuring. */
    bool Bad = false, Changed = false;
    bool Bad = false, Changed = false;
-   do {
+   const unsigned int max_loops = _config->FindI("APT::pkgPackageManager::MaxLoopCount", 100);
+   unsigned int i=0;
+   do
+   {
       Changed = false;
       Changed = false;
       for (DepIterator D = instVer.DependsList(); D.end() == false; )
       for (DepIterator D = instVer.DependsList(); D.end() == false; )
       {
       {
@@ -460,6 +463,8 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	 if (Bad == true && Changed == false && Debug == true)
 	 if (Bad == true && Changed == false && Debug == true)
 	    std::clog << OutputInDepth(Depth) << "Could not satisfy " << Start << std::endl;
 	    std::clog << OutputInDepth(Depth) << "Could not satisfy " << Start << std::endl;
       }
       }
+      if (i++ > max_loops)
+         return _error->Error("Internal error: MaxLoopCount reached in SmartUnPack for %s, aborting", Pkg.FullName().c_str());
    } while (Changed == true);
    } while (Changed == true);
    
    
    if (Bad) {
    if (Bad) {
@@ -596,7 +601,10 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
       This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured),
       This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured),
       or by the ConfigureAll call at the end of the for loop in OrderInstall. */
       or by the ConfigureAll call at the end of the for loop in OrderInstall. */
    bool Changed = false;
    bool Changed = false;
-   do {
+   const unsigned int max_loops = _config->FindI("APT::pkgPackageManager::MaxLoopCount", 100);
+   unsigned int i;
+   do 
+   {
       Changed = false;
       Changed = false;
       for (DepIterator D = instVer.DependsList(); D.end() == false; )
       for (DepIterator D = instVer.DependsList(); D.end() == false; )
       {
       {
@@ -821,6 +829,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 	    }
 	    }
 	 }
 	 }
       }
       }
+      if (i++ > max_loops)
+         return _error->Error("Internal error: MaxLoopCount reached in SmartConfigure for %s, aborting", Pkg.FullName().c_str());
    } while (Changed == true);
    } while (Changed == true);
    
    
    // Check for reverse conflicts.
    // Check for reverse conflicts.

+ 3 - 0
debian/changelog

@@ -3,6 +3,9 @@ apt (0.8.16~exp14) UNRELEASED; urgency=low
   [ Michael Vogt ]
   [ Michael Vogt ]
   * apt-pkg/packagemanager.cc:
   * apt-pkg/packagemanager.cc:
     - fix inconsistent clog/cout usage in the debug output
     - fix inconsistent clog/cout usage in the debug output
+    - add APT::pkgPackageManager::MaxLoopCount to ensure that the
+      ordering code does not get into a endless loop when it flip-flops
+      between two states
   
   
   [ David Kalnischkies ]
   [ David Kalnischkies ]
   * apt-pkg/packagemanager.cc:
   * apt-pkg/packagemanager.cc: