diff options
author | Sam Yates <halfflat@gmail.com> | 2018-05-31 17:00:45 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-06-14 18:28:03 (GMT) |
commit | c76c1ea2086a071c0afb143918b275bb8cf3b806 (patch) | |
tree | 7184a4caf92cbfe339d5e2233e5d30e12895dbe6 /Source/cmFindProgramCommand.cxx | |
parent | 575f97763f08f0358cb5ccb4ac937d1610cbbbf7 (diff) | |
download | CMake-c76c1ea2086a071c0afb143918b275bb8cf3b806.zip CMake-c76c1ea2086a071c0afb143918b275bb8cf3b806.tar.gz CMake-c76c1ea2086a071c0afb143918b275bb8cf3b806.tar.bz2 |
find_program: Consider CWD only for paths with separator
find_program() incorrectly prepended search path components
to absolute file paths, and incorrectly searched the current
working directory for files that contained no directory
separators.
* Replace calls cmFindProgramHelper::CheckDirectory(std::string())
with call of new method cmFindProgramHelper::CheckCompoundNames()
that checks for the presence of a directory separator in the
file name.
* Use cmSystemTools::CollapseCombinedPath rather than string
concatenation to properly combine absolute file names with
search path components.
* Add unit tests to verify corrections.
Fixes: #18044
Diffstat (limited to 'Source/cmFindProgramCommand.cxx')
-rw-r--r-- | Source/cmFindProgramCommand.cxx | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 13a18e2..db34077 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -34,6 +34,9 @@ struct cmFindProgramHelper // Current names under consideration. std::vector<std::string> Names; + // Current name with extension under consideration. + std::string TestNameExt; + // Current full path under consideration. std::string TestPath; @@ -43,6 +46,19 @@ struct cmFindProgramHelper this->Names.clear(); this->AddName(name); } + bool CheckCompoundNames() + { + for (std::string const& n : this->Names) { + // Only perform search relative to current directory if the file name + // contains a directory separator. + if (n.find('/') != std::string::npos) { + if (this->CheckDirectoryForName("", n)) { + return true; + } + } + } + return false; + } bool CheckDirectory(std::string const& path) { for (std::string const& n : this->Names) { @@ -55,14 +71,16 @@ struct cmFindProgramHelper bool CheckDirectoryForName(std::string const& path, std::string const& name) { for (std::string const& ext : this->Extensions) { - this->TestPath = path; - this->TestPath += name; if (!ext.empty() && cmSystemTools::StringEndsWith(name, ext.c_str())) { continue; } - this->TestPath += ext; + this->TestNameExt = name; + this->TestNameExt += ext; + this->TestPath = + cmSystemTools::CollapseCombinedPath(path, this->TestNameExt); + if (cmSystemTools::FileExists(this->TestPath, true)) { - this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath); + this->BestPath = this->TestPath; return true; } } @@ -145,8 +163,8 @@ std::string cmFindProgramCommand::FindNormalProgramNamesPerDir() helper.AddName(n); } - // Check for the names themselves (e.g. absolute paths). - if (helper.CheckDirectory(std::string())) { + // Check for the names themselves if they contain a directory separator. + if (helper.CheckCompoundNames()) { return helper.BestPath; } @@ -168,8 +186,8 @@ std::string cmFindProgramCommand::FindNormalProgramDirsPerName() // Switch to searching for this name. helper.SetName(n); - // Check for the name by itself (e.g. an absolute path). - if (helper.CheckDirectory(std::string())) { + // Check for the names themselves if they contain a directory separator. + if (helper.CheckCompoundNames()) { return helper.BestPath; } |