Skip to content
This repository
Browse code

Merge pull request #2475 from cptspiff/prevent_infinite_loop

fixed: prevent infinite loop in add-on dependency checks
  • Loading branch information...
commit b0825b1a212849e52fca27409ea87e81591f7cf4 2 parents 7f0b5c6 + e137421
Martijn Kaijser authored March 21, 2013
21  xbmc/addons/AddonInstaller.cpp
@@ -313,6 +313,14 @@ void CAddonInstaller::InstallFromXBMCRepo(const set<CStdString> &addonIDs)
313 313
 
314 314
 bool CAddonInstaller::CheckDependencies(const AddonPtr &addon)
315 315
 {
  316
+  std::vector<std::string> preDeps;
  317
+  preDeps.push_back(addon->ID());
  318
+  return CheckDependencies(addon, preDeps);
  319
+}
  320
+
  321
+bool CAddonInstaller::CheckDependencies(const AddonPtr &addon,
  322
+                                        std::vector<std::string>& preDeps)
  323
+{
316 324
   if (!addon.get())
317 325
     return true; // a NULL addon has no dependencies
318 326
   ADDONDEPS deps = addon->GetDeps();
@@ -333,16 +341,15 @@ bool CAddonInstaller::CheckDependencies(const AddonPtr &addon)
333 341
         return false;
334 342
       }
335 343
     }
336  
-    // prevent infinite loops
337  
-    if (dep && dep->ID() == addon->ID())
338  
-    {
339  
-      CLog::Log(LOGERROR, "Addon %s depends on itself, ignoring", addon->ID().c_str());
340  
-      return false;
341  
-    }
342 344
     // at this point we have our dep, or the dep is optional (and we don't have it) so check that it's OK as well
343 345
     // TODO: should we assume that installed deps are OK?
344  
-    if (dep && !CheckDependencies(dep))
  346
+    if (dep && 
  347
+       std::find(preDeps.begin(), preDeps.end(), dep->ID()) == preDeps.end() &&
  348
+       !CheckDependencies(dep, preDeps))
  349
+    {
345 350
       return false;
  351
+    }
  352
+    preDeps.push_back(dep->ID());
346 353
   }
347 354
   return true;
348 355
 }
10  xbmc/addons/AddonInstaller.h
@@ -122,6 +122,16 @@ class CAddonInstaller : public IJobCallback
122 122
    */
123 123
   bool DoInstall(const ADDON::AddonPtr &addon, const CStdString &hash = "", bool update = false, const CStdString &referer = "", bool background = true);
124 124
 
  125
+  /*! \brief Check whether dependencies of an addon exist or are installable.
  126
+   Iterates through the addon's dependencies, checking they're installed or installable.
  127
+   Each dependency must also satisfies CheckDependencies in turn.
  128
+   \param addon the addon to check
  129
+   \param preDeps previous dependencies encountered during recursion. aids in avoiding infinite recursion
  130
+   \return true if dependencies are available, false otherwise.
  131
+   */
  132
+  bool CheckDependencies(const ADDON::AddonPtr &addon,
  133
+                         std::vector<std::string>& preDeps);
  134
+
125 135
   void PrunePackageCache();
126 136
   int64_t EnumeratePackageFolder(std::map<CStdString,CFileItemList*>& result);
127 137
 

0 notes on commit b0825b1

Please sign in to comment.
Something went wrong with that request. Please try again.