Improved the symlink loop detection on application startup.

This commit is contained in:
Leon Styhre 2023-01-16 17:43:02 +01:00
parent cc8dfe20ca
commit 7e30f3f3cf
2 changed files with 34 additions and 8 deletions

View file

@ -196,6 +196,7 @@ SystemData::SystemData(const std::string& name,
, mSortName {sortName} , mSortName {sortName}
, mEnvData {envData} , mEnvData {envData}
, mThemeFolder {themeFolder} , mThemeFolder {themeFolder}
, mSymlinkMaxDepthReached {false}
, mIsCollectionSystem {CollectionSystem} , mIsCollectionSystem {CollectionSystem}
, mIsCustomCollectionSystem {CustomCollectionSystem} , mIsCustomCollectionSystem {CustomCollectionSystem}
, mIsGroupedCustomCollectionSystem {false} , mIsGroupedCustomCollectionSystem {false}
@ -265,6 +266,9 @@ void SystemData::setIsGameSystemStatus()
bool SystemData::populateFolder(FileData* folder) bool SystemData::populateFolder(FileData* folder)
{ {
if (mSymlinkMaxDepthReached)
return false;
std::string filePath; std::string filePath;
std::string extension; std::string extension;
const std::string& folderPath {folder->getPath()}; const std::string& folderPath {folder->getPath()};
@ -345,22 +349,43 @@ bool SystemData::populateFolder(FileData* folder)
// Add directories that also do not match an extension as folders. // Add directories that also do not match an extension as folders.
if (!isGame && isDirectory) { if (!isGame && isDirectory) {
// Make sure that it's not a recursive symlink pointing to a location higher in the // Make sure that it's not a recursive symlink as the application would run into a
// hierarchy as the application would run forever trying to resolve the link. // loop trying to resolve the link.
if (Utils::FileSystem::isSymlink(filePath)) { if (Utils::FileSystem::isSymlink(filePath)) {
bool recursiveSymlink {false};
const std::string& canonicalPath {Utils::FileSystem::getCanonicalPath(filePath)}; const std::string& canonicalPath {Utils::FileSystem::getCanonicalPath(filePath)};
const std::string& canonicalStartPath { const std::string& canonicalStartPath {
Utils::FileSystem::getCanonicalPath(mEnvData->mStartPath)}; Utils::FileSystem::getCanonicalPath(mEnvData->mStartPath)};
if (canonicalPath.size() >= canonicalStartPath.size()) { // Last resort hack to prevent recursive symlinks in some really unusual situations.
if (filePath.length() > canonicalStartPath.length() + 100) {
int folderDepth {0};
const std::string& path {filePath.substr(canonicalStartPath.length())};
for (char character : path) {
if (character == '/') {
++folderDepth;
if (folderDepth == 20) {
LOG(LogWarning) << "Skipped \"" << filePath
<< "\" as it seems to be a recursive symlink";
mSymlinkMaxDepthReached = true;
return false;
}
}
}
}
if (canonicalStartPath.find(canonicalPath) != std::string::npos)
recursiveSymlink = true;
else if (canonicalPath.size() >= canonicalStartPath.size() &&
canonicalPath.find(canonicalStartPath) != std::string::npos) {
const std::string& combinedPath { const std::string& combinedPath {
mEnvData->mStartPath + mEnvData->mStartPath +
canonicalPath.substr(canonicalStartPath.size(), canonicalPath.substr(canonicalStartPath.size(),
canonicalStartPath.size() - canonicalPath.size())}; canonicalStartPath.size() - canonicalPath.size())};
if (filePath.find(combinedPath) == 0) { if (Utils::FileSystem::getParent(filePath).find(combinedPath) == 0)
LOG(LogWarning) recursiveSymlink = true;
<< "Skipped \"" << filePath << "\" as it's a recursive symlink"; }
continue; if (recursiveSymlink) {
} LOG(LogWarning) << "Skipped \"" << filePath << "\" as it's a recursive symlink";
continue;
} }
} }

View file

@ -153,6 +153,7 @@ private:
std::string mThemeFolder; std::string mThemeFolder;
std::shared_ptr<ThemeData> mTheme; std::shared_ptr<ThemeData> mTheme;
bool mSymlinkMaxDepthReached;
bool mIsCollectionSystem; bool mIsCollectionSystem;
bool mIsCustomCollectionSystem; bool mIsCustomCollectionSystem;
bool mIsGroupedCustomCollectionSystem; bool mIsGroupedCustomCollectionSystem;