Normalize PWD environment variable before using it

In commit 5aed3ee49d (cmSystemTools: Add GetLogicalWorkingDirectory,
2024-10-28, v4.0.0-rc1~528^2~6) we incorrectly trusted `PWD` to be a
normalized path so long as its realpath matches the current working
directory.

Fixes: #26870
This commit is contained in:
Brad King
2025-04-15 08:41:36 -04:00
parent 813f6c263e
commit cd4e72ca08
3 changed files with 34 additions and 8 deletions

View File

@@ -3007,10 +3007,11 @@ std::string InitLogicalWorkingDirectory()
{ {
std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory(); std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
std::string pwd; std::string pwd;
if (cmSystemTools::GetEnv("PWD", pwd)) { if (cmSystemTools::GetEnv("PWD", pwd) &&
cmSystemTools::FileIsFullPath(pwd)) {
std::string const pwd_real = cmSystemTools::GetRealPath(pwd); std::string const pwd_real = cmSystemTools::GetRealPath(pwd);
if (pwd_real == cwd) { if (pwd_real == cwd) {
cwd = std::move(pwd); cwd = cmSystemTools::ToNormalizedPathOnDisk(std::move(pwd));
} }
} }
return cwd; return cwd;

View File

@@ -896,10 +896,31 @@ run_cmake_command(E_sleep-bad-arg2 ${CMAKE_COMMAND} -E sleep 1 -1)
run_cmake_command(E_sleep-one-tenth ${CMAKE_COMMAND} -E sleep 0.1) run_cmake_command(E_sleep-one-tenth ${CMAKE_COMMAND} -E sleep 0.1)
run_cmake_command(P_directory ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}) run_cmake_command(P_directory ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR})
run_cmake_command(P_working-dir ${CMAKE_COMMAND} -DEXPECTED_WORKING_DIR=${RunCMake_BINARY_DIR}/P_working-dir-build -P ${RunCMake_SOURCE_DIR}/P_working-dir.cmake)
# Documented to return the same result as above even if -S and -B are set to something else. block()
# Tests the values of CMAKE_BINARY_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_SOURCE_DIR. set(expect ${RunCMake_BINARY_DIR}/P_working-dir-build)
run_cmake_command(P_working-dir ${CMAKE_COMMAND} -DEXPECTED_WORKING_DIR=${RunCMake_BINARY_DIR}/P_working-dir-build -P ${RunCMake_SOURCE_DIR}/P_working-dir.cmake -S something_else -B something_else_1) run_cmake_script(P_working-dir -DEXPECTED_WORKING_DIR=${expect})
# -S and -B have no effect on script mode variables.
set(RunCMake_TEST_VARIANT_DESCRIPTION "-S-B")
run_cmake_script(P_working-dir -DEXPECTED_WORKING_DIR=${expect} -S something_else -B something_else_1)
# Relative PWD is ignored.
set(RunCMake_TEST_VARIANT_DESCRIPTION "-PWD-.")
set(RunCMake_TEST_COMMAND_PWD .)
run_cmake_script(P_working-dir -DEXPECTED_WORKING_DIR=${expect})
# Lower-case PWD is ignored on case-sensitive filesystems
# and case-normalized on case-insensitive filesystems.
set(RunCMake_TEST_VARIANT_DESCRIPTION "-PWD-case")
string(TOLOWER "${expect}" RunCMake_TEST_COMMAND_PWD)
run_cmake_script(P_working-dir -DEXPECTED_WORKING_DIR=${expect})
# Backslashed PWD is normalized on Windows and ignored elsewhere.
set(RunCMake_TEST_VARIANT_DESCRIPTION "-PWD-backslash")
string(REPLACE "/" "\\" RunCMake_TEST_COMMAND_PWD "${expect}")
run_cmake_script(P_working-dir -DEXPECTED_WORKING_DIR=${expect})
endblock()
# Place an initial cache where C_basic will find it when passed the relative path "..". # Place an initial cache where C_basic will find it when passed the relative path "..".
file(COPY ${RunCMake_SOURCE_DIR}/C_basic_initial-cache.txt DESTINATION ${RunCMake_BINARY_DIR}) file(COPY ${RunCMake_SOURCE_DIR}/C_basic_initial-cache.txt DESTINATION ${RunCMake_BINARY_DIR})

View File

@@ -164,8 +164,12 @@ function(run_cmake test)
else() else()
set(old_pwd) set(old_pwd)
endif() endif()
# Emulate a shell using this directory. if(RunCMake_TEST_COMMAND_PWD)
set(ENV{PWD} "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}") set(ENV{PWD} "${RunCMake_TEST_COMMAND_PWD}")
else()
# Emulate a shell using this directory.
set(ENV{PWD} "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}")
endif()
cmake_language(EVAL CODE "${_code}") cmake_language(EVAL CODE "${_code}")
if(DEFINED old_pwd) if(DEFINED old_pwd)
set(ENV{PWD} "${old_pwd}") set(ENV{PWD} "${old_pwd}")