From d6781e7f93024a4ba6bd36e81e100475601e5a3c Mon Sep 17 00:00:00 2001 From: paxcut <53811119+paxcut@users.noreply.github.com> Date: Wed, 28 Jan 2026 16:12:36 -0700 Subject: [PATCH] fix: issue 2631 (#2633) problem occurs because there is no check for duplicate entries in the paths vector. The fix is implemented using the combination of two containers; a vector to ensure the insertion order and a set to ensure the uniqueness the entries. The set first attempts to insert the new path and uses the return of insertion to decide if the vector needs to be updated. --- lib/libimhex/source/helpers/default_paths.cpp | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/libimhex/source/helpers/default_paths.cpp b/lib/libimhex/source/helpers/default_paths.cpp index c0093cd3e..d570afc1e 100644 --- a/lib/libimhex/source/helpers/default_paths.cpp +++ b/lib/libimhex/source/helpers/default_paths.cpp @@ -5,6 +5,7 @@ #include #include +#include #if defined(OS_WINDOWS) #include @@ -17,6 +18,13 @@ namespace hex::paths { std::vector getDataPaths(bool includeSystemFolders) { std::vector paths; + std::set uniquePaths; + + const auto emplaceUniquePath = [&](const std::fs::path &path) { + auto duplicate = uniquePaths.insert(path); + if (duplicate.second) + paths.emplace_back(path); + }; #if defined(OS_WINDOWS) @@ -25,21 +33,22 @@ namespace hex::paths { if (!ImHexApi::System::isPortableVersion()) { PWSTR wAppDataPath = nullptr; if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &wAppDataPath))) { - paths.emplace_back(wAppDataPath); + emplaceUniquePath(wAppDataPath); CoTaskMemFree(wAppDataPath); } } #elif defined(OS_MACOS) - paths.push_back(wolv::io::fs::getApplicationSupportDirectoryPath() / "imhex"); + emplaceUniquePath(wolv::io::fs::getApplicationSupportDirectoryPath() / "imhex"); #elif defined(OS_LINUX) || defined(OS_WEB) - paths.push_back(xdg::DataHomeDir()); + emplaceUniquePath(xdg::DataHomeDir()); auto dataDirs = xdg::DataDirs(); - std::ranges::copy(dataDirs, std::back_inserter(paths)); + for (const auto &path : dataDirs) + emplaceUniquePath(path); #endif @@ -47,18 +56,21 @@ namespace hex::paths { if (includeSystemFolders) { if (auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value()) { - paths.push_back(executablePath->parent_path()); + emplaceUniquePath(executablePath->parent_path()); } } #else - for (auto &path : paths) + uniquePaths.clear(); + for (auto &path : paths) { path = path / "imhex"; + uniquePaths.insert(path); + } if (ImHexApi::System::isPortableVersion() || includeSystemFolders) { if (auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value()) - paths.push_back(executablePath->parent_path()); + emplaceUniquePath(executablePath->parent_path()); } #endif @@ -66,11 +78,12 @@ namespace hex::paths { // Add additional data directories to the path auto additionalDirs = ImHexApi::System::getAdditionalFolderPaths(); - std::ranges::copy(additionalDirs, std::back_inserter(paths)); + for (const auto &path : additionalDirs) + emplaceUniquePath(path); // Add the project file directory to the path, if one is loaded if (ProjectFile::hasPath()) { - paths.push_back(ProjectFile::getPath().parent_path()); + emplaceUniquePath(ProjectFile::getPath().parent_path()); } return paths;