浏览代码

find_program: Properly decode URL for bundle exe name with spaces

Fixes: #20817
Craig Scott 5 年之前
父节点
当前提交
d3fd518c03

+ 6 - 7
Source/cmFindProgramCommand.cxx

@@ -266,14 +266,13 @@ std::string cmFindProgramCommand::GetBundleExecutable(
 
   if (executableURL != nullptr) {
     const int MAX_OSX_PATH_SIZE = 1024;
-    char buffer[MAX_OSX_PATH_SIZE];
+    UInt8 buffer[MAX_OSX_PATH_SIZE];
 
-    // Convert the CFString to a C string
-    CFStringGetCString(CFURLGetString(executableURL), buffer,
-                       MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8);
-
-    // And finally to a c++ string
-    executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);
+    if (CFURLGetFileSystemRepresentation(executableURL, false, buffer,
+                                         MAX_OSX_PATH_SIZE)) {
+      executable = bundlePath + "/Contents/MacOS/" +
+        std::string(reinterpret_cast<char*>(buffer));
+    }
     // Only release CFURLRef if it's not null
     CFRelease(executableURL);
   }

+ 1 - 0
Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt

@@ -0,0 +1 @@
+-- FakeApp_EXECUTABLE='.*/Tests/RunCMake/find_program/BundleSpaceInName-build/Fake app.app/Contents/MacOS/Fake app'

+ 8 - 0
Tests/RunCMake/find_program/BundleSpaceInName.cmake

@@ -0,0 +1,8 @@
+set(fakeApp "${CMAKE_CURRENT_BINARY_DIR}/Fake app.app/Contents/MacOS/Fake app")
+file(WRITE "${fakeApp}" "#!/bin/sh\n")
+execute_process(COMMAND chmod a+rx "${fakeApp}")
+
+find_program(FakeApp_EXECUTABLE NAMES "Fake app" NO_DEFAULT_PATH
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+)
+message(STATUS "FakeApp_EXECUTABLE='${FakeApp_EXECUTABLE}'")

+ 4 - 0
Tests/RunCMake/find_program/RunCMakeTest.cmake

@@ -14,3 +14,7 @@ endif()
 if(UNIX)
   run_cmake(ExeNoRead)
 endif()
+
+if(APPLE)
+  run_cmake(BundleSpaceInName)
+endif()