App: Sanitize all paths for null characters (#23821)
* App: Sanitize all paths for null characters * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Apply suggestions from code review --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Kacper Donat <kadet1090@gmail.com>
This commit is contained in:
@@ -273,11 +273,19 @@ bool ApplicationDirectories::startSafeMode(std::map<std::string,std::string>& mC
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::filesystem::path ApplicationDirectories::sanitizePath(const std::string& pathAsString)
|
||||||
|
{
|
||||||
|
size_t positionOfFirstNull = pathAsString.find('\0');
|
||||||
|
if (positionOfFirstNull != std::string::npos) {
|
||||||
|
return {pathAsString.substr(0, positionOfFirstNull)};
|
||||||
|
}
|
||||||
|
return {pathAsString};
|
||||||
|
}
|
||||||
|
|
||||||
void ApplicationDirectories::configureResourceDirectory(const std::map<std::string,std::string>& mConfig) {
|
void ApplicationDirectories::configureResourceDirectory(const std::map<std::string,std::string>& mConfig) {
|
||||||
#ifdef RESOURCEDIR
|
#ifdef RESOURCEDIR
|
||||||
// #6892: Conda may inject null characters => remove them using c_str()
|
// #6892: Conda may inject null characters
|
||||||
fs::path path {std::string(RESOURCEDIR).c_str()};
|
fs::path path = sanitizePath(RESOURCEDIR);
|
||||||
if (path.is_absolute()) {
|
if (path.is_absolute()) {
|
||||||
_resource = path;
|
_resource = path;
|
||||||
} else {
|
} else {
|
||||||
@@ -290,8 +298,8 @@ void ApplicationDirectories::configureResourceDirectory(const std::map<std::stri
|
|||||||
|
|
||||||
void ApplicationDirectories::configureLibraryDirectory(const std::map<std::string,std::string>& mConfig) {
|
void ApplicationDirectories::configureLibraryDirectory(const std::map<std::string,std::string>& mConfig) {
|
||||||
#ifdef LIBRARYDIR
|
#ifdef LIBRARYDIR
|
||||||
// #6892: Conda may inject null characters => remove them using c_str()
|
// #6892: Conda may inject null characters
|
||||||
fs::path path {std::string(LIBRARYDIR).c_str()};
|
fs::path path = sanitizePath(LIBRARYDIR);
|
||||||
if (path.is_absolute()) {
|
if (path.is_absolute()) {
|
||||||
_library = path;
|
_library = path;
|
||||||
} else {
|
} else {
|
||||||
@@ -306,8 +314,8 @@ void ApplicationDirectories::configureLibraryDirectory(const std::map<std::strin
|
|||||||
void ApplicationDirectories::configureHelpDirectory(const std::map<std::string,std::string>& mConfig)
|
void ApplicationDirectories::configureHelpDirectory(const std::map<std::string,std::string>& mConfig)
|
||||||
{
|
{
|
||||||
#ifdef DOCDIR
|
#ifdef DOCDIR
|
||||||
// #6892: Conda may inject null characters => remove them using c_str()
|
// #6892: Conda may inject null characters
|
||||||
fs::path path {std::string(DOCDIR).c_str()};
|
fs::path path = sanitizePath(DOCDIR);
|
||||||
if (path.is_absolute()) {
|
if (path.is_absolute()) {
|
||||||
_help = path;
|
_help = path;
|
||||||
} else {
|
} else {
|
||||||
@@ -332,7 +340,8 @@ fs::path ApplicationDirectories::getUserHome()
|
|||||||
if (!result || error != 0) {
|
if (!result || error != 0) {
|
||||||
throw Base::RuntimeError("Getting HOME path from system failed!");
|
throw Base::RuntimeError("Getting HOME path from system failed!");
|
||||||
}
|
}
|
||||||
path = Base::FileInfo::stringToPath(result->pw_dir);
|
std::string sanitizedPath = sanitizePath(pwd.pw_dir);
|
||||||
|
path = Base::FileInfo::stringToPath(sanitizedPath);
|
||||||
#else
|
#else
|
||||||
path = Base::FileInfo::stringToPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString());
|
path = Base::FileInfo::stringToPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString());
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -233,6 +233,12 @@ namespace App {
|
|||||||
/// \return The version tuple.
|
/// \return The version tuple.
|
||||||
static std::tuple<int, int> extractVersionFromConfigMap(const std::map<std::string,std::string> &config);
|
static std::tuple<int, int> extractVersionFromConfigMap(const std::map<std::string,std::string> &config);
|
||||||
|
|
||||||
|
/// A utility method to remove any stray null characters from a path (Conda sometimes
|
||||||
|
/// injects these for unknown reasons -- see #6892 in the bug tracker).
|
||||||
|
/// \param pathAsString The std::string path to sanitize
|
||||||
|
/// \returns A path with any stray nulls removed
|
||||||
|
static std::filesystem::path sanitizePath(const std::string& pathAsString);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::tuple<int, int> _currentVersion;
|
std::tuple<int, int> _currentVersion;
|
||||||
std::filesystem::path _home;
|
std::filesystem::path _home;
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ public:
|
|||||||
{
|
{
|
||||||
return extractVersionFromConfigMap(config);
|
return extractVersionFromConfigMap(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::filesystem::path wrapSanitizePath(const std::string& pathAsString)
|
||||||
|
{
|
||||||
|
return sanitizePath(pathAsString);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ApplicationDirectoriesTest: public ::testing::Test
|
class ApplicationDirectoriesTest: public ::testing::Test
|
||||||
@@ -747,6 +752,25 @@ TEST_F(ApplicationDirectoriesTest, extractVersionNegativeNumbersPassThrough)
|
|||||||
EXPECT_EQ(min, -7);
|
EXPECT_EQ(min, -7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_F(ApplicationDirectoriesTest, sanitizeRemovesNullCharacterAtEnd)
|
||||||
|
{
|
||||||
|
std::string input = std::string("valid_path") + '\0' + "junk_after";
|
||||||
|
std::filesystem::path result = ApplicationDirectoriesTestClass::wrapSanitizePath(input);
|
||||||
|
|
||||||
|
EXPECT_EQ(result.string(), "valid_path");
|
||||||
|
EXPECT_EQ(result.string().find('\0'), std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ApplicationDirectoriesTest, sanitizeReturnsUnchangedIfNoNullCharacter)
|
||||||
|
{
|
||||||
|
std::string input = "clean_path/without_nulls";
|
||||||
|
std::filesystem::path result = ApplicationDirectoriesTestClass::wrapSanitizePath(input);
|
||||||
|
|
||||||
|
EXPECT_EQ(result.string(), input);
|
||||||
|
EXPECT_EQ(result.string().find('\0'), std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
/* NOLINTEND(
|
/* NOLINTEND(
|
||||||
readability-magic-numbers,
|
readability-magic-numbers,
|
||||||
cppcoreguidelines-avoid-magic-numbers,
|
cppcoreguidelines-avoid-magic-numbers,
|
||||||
|
|||||||
Reference in New Issue
Block a user