From 94d65a95357f18de9597ec94623d13be6c4cf93d Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 31 Mar 2025 11:51:46 -0400 Subject: get_filename_component: Restore lexical preprocessing of REALPATH for compat Revert commit c554437733 (get_filename_component: Fix REALPATH for .. after symlink, 2024-11-21, v4.0.0-rc1~411^2) because it changed existing behavior without a policy. Also add a test case for the old behavior. Note that we have policy `CMP0152` to fix this for `file(REAL_PATH)`, but it does not affect `get_filename_component(... REALPATH)`. A new policy would be needed for the latter. Fixes: #26815 Issue: #26472 --- Source/cmGetFilenameComponentCommand.cxx | 12 +++--------- .../CMakeTests/GetFilenameComponentRealpathTest.cmake.in | 16 ++++++++++++++++ .../get_filename_component/KnownComponents.cmake | 8 -------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx index 1543ca6..dee5c3f 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx @@ -107,15 +107,9 @@ bool cmGetFilenameComponentCommand(std::vector const& args, } } } - if (args[2] == "ABSOLUTE") { - // Collapse the path to its simplest form. - result = cmSystemTools::CollapseFullPath(filename, baseDir); - } else { - // Convert relative paths to absolute paths - result = filename; - if (!cmSystemTools::FileIsFullPath(result)) { - result = cmStrCat(baseDir, '/', result); - } + // Collapse the path to its simplest form. + result = cmSystemTools::CollapseFullPath(filename, baseDir); + if (args[2] == "REALPATH") { // Resolve symlinks if possible result = cmSystemTools::GetRealPath(result); } diff --git a/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in b/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in index 22f6afd..4701fab 100644 --- a/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in +++ b/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in @@ -13,6 +13,22 @@ if(NOT nonexistent2 STREQUAL "${bindir}/THIS_IS_A_NONEXISTENT_FILE") endif() # +# Test treatment of .. after file name +# +foreach(c REALPATH ABSOLUTE) + get_filename_component(dir "${CMAKE_CURRENT_LIST_DIR}" ${c}) + get_filename_component(fileDotDot "${CMAKE_CURRENT_LIST_FILE}/.." ${c}) + if(NOT "${fileDotDot}" STREQUAL "${dir}") + message(FATAL_ERROR + "${c} did not resolve\n" + " ${CMAKE_CURRENT_LIST_FILE}/..\n" + "lexically:\n" + " ${fileDotDot}" + ) + endif() +endforeach() + +# # Test treatment of relative paths # foreach(c REALPATH ABSOLUTE) diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake index 93f9270..34af12e 100644 --- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake +++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake @@ -159,11 +159,3 @@ foreach(thisVar ${non_cache_vars}) message(SEND_ERROR "${thisVar} not found in regular variable list.") endif() endforeach() - -if(UNIX) - file(MAKE_DIRECTORY . "${CMAKE_CURRENT_BINARY_DIR}/subdir") - file(CREATE_LINK . "${CMAKE_CURRENT_BINARY_DIR}/subdir/symlink-to-dot" SYMBOLIC) - get_filename_component(realpath_actual "${CMAKE_CURRENT_BINARY_DIR}/subdir/symlink-to-dot/.." REALPATH) - get_filename_component(realpath_expect "${CMAKE_CURRENT_BINARY_DIR}" REALPATH) - check("symlink parent" "${realpath_actual}" "${realpath_expect}") -endif(UNIX) -- cgit v0.12