Skip to content

Commit

Permalink
Merge pull request #2475 from cptspiff/prevent_infinite_loop
Browse files Browse the repository at this point in the history
fixed: prevent infinite loop in add-on dependency checks
  • Loading branch information
MartijnKaijser committed Mar 21, 2013
2 parents 7f0b5c6 + e137421 commit b0825b1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
21 changes: 14 additions & 7 deletions xbmc/addons/AddonInstaller.cpp
Expand Up @@ -312,6 +312,14 @@ void CAddonInstaller::InstallFromXBMCRepo(const set<CStdString> &addonIDs)
} }


bool CAddonInstaller::CheckDependencies(const AddonPtr &addon) bool CAddonInstaller::CheckDependencies(const AddonPtr &addon)
{
std::vector<std::string> preDeps;
preDeps.push_back(addon->ID());
return CheckDependencies(addon, preDeps);
}

bool CAddonInstaller::CheckDependencies(const AddonPtr &addon,
std::vector<std::string>& preDeps)
{ {
if (!addon.get()) if (!addon.get())
return true; // a NULL addon has no dependencies return true; // a NULL addon has no dependencies
Expand All @@ -333,16 +341,15 @@ bool CAddonInstaller::CheckDependencies(const AddonPtr &addon)
return false; return false;
} }
} }
// prevent infinite loops
if (dep && dep->ID() == addon->ID())
{
CLog::Log(LOGERROR, "Addon %s depends on itself, ignoring", addon->ID().c_str());
return false;
}
// 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 // 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
// TODO: should we assume that installed deps are OK? // TODO: should we assume that installed deps are OK?
if (dep && !CheckDependencies(dep)) if (dep &&
std::find(preDeps.begin(), preDeps.end(), dep->ID()) == preDeps.end() &&
!CheckDependencies(dep, preDeps))
{
return false; return false;
}
preDeps.push_back(dep->ID());
} }
return true; return true;
} }
Expand Down
10 changes: 10 additions & 0 deletions xbmc/addons/AddonInstaller.h
Expand Up @@ -122,6 +122,16 @@ class CAddonInstaller : public IJobCallback
*/ */
bool DoInstall(const ADDON::AddonPtr &addon, const CStdString &hash = "", bool update = false, const CStdString &referer = "", bool background = true); bool DoInstall(const ADDON::AddonPtr &addon, const CStdString &hash = "", bool update = false, const CStdString &referer = "", bool background = true);


/*! \brief Check whether dependencies of an addon exist or are installable.
Iterates through the addon's dependencies, checking they're installed or installable.
Each dependency must also satisfies CheckDependencies in turn.
\param addon the addon to check
\param preDeps previous dependencies encountered during recursion. aids in avoiding infinite recursion
\return true if dependencies are available, false otherwise.
*/
bool CheckDependencies(const ADDON::AddonPtr &addon,
std::vector<std::string>& preDeps);

void PrunePackageCache(); void PrunePackageCache();
int64_t EnumeratePackageFolder(std::map<CStdString,CFileItemList*>& result); int64_t EnumeratePackageFolder(std::map<CStdString,CFileItemList*>& result);


Expand Down

0 comments on commit b0825b1

Please sign in to comment.