From d3fd518c0316b15e4680c32808788935bf8c5c3d Mon Sep 17 00:00:00 2001 From: Craig Scott Date: Sun, 14 Jun 2020 18:21:35 +1000 Subject: find_program: Properly decode URL for bundle exe name with spaces Fixes: #20817 --- Source/cmFindProgramCommand.cxx | 13 ++++++------- Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt | 1 + Tests/RunCMake/find_program/BundleSpaceInName.cmake | 8 ++++++++ Tests/RunCMake/find_program/RunCMakeTest.cmake | 4 ++++ 4 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt create mode 100644 Tests/RunCMake/find_program/BundleSpaceInName.cmake diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 599b1d2..d4b0ee1 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/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(buffer)); + } // Only release CFURLRef if it's not null CFRelease(executableURL); } diff --git a/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt b/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt new file mode 100644 index 0000000..331d465 --- /dev/null +++ b/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' diff --git a/Tests/RunCMake/find_program/BundleSpaceInName.cmake b/Tests/RunCMake/find_program/BundleSpaceInName.cmake new file mode 100644 index 0000000..9152d5b --- /dev/null +++ b/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}'") diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake index 95ffd84..be70deb 100644 --- a/Tests/RunCMake/find_program/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake @@ -14,3 +14,7 @@ endif() if(UNIX) run_cmake(ExeNoRead) endif() + +if(APPLE) + run_cmake(BundleSpaceInName) +endif() -- cgit v0.12