From 94d65a95357f18de9597ec94623d13be6c4cf93d Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 31 Mar 2025 11:51:46 -0400 Subject: [PATCH] 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 +++--------- .../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 1543ca6f09..dee5c3f009 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 22f6afd3b6..4701fab729 100644 --- a/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in +++ b/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in @@ -12,6 +12,22 @@ if(NOT nonexistent2 STREQUAL "${bindir}/THIS_IS_A_NONEXISTENT_FILE") message(FATAL_ERROR "ABSOLUTE is not preserving nonexistent files") 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 # diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake index 93f9270faf..34af12eb04 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)