Selaa lähdekoodia

cmake: Fix `-E time` argument passing to child

Since this command was introduced in 2002 it has incorrectly constructed
the child process command line by concatenating arguments separated by
spaces with no quoting.  Fix this by passing the command argument vector
directly to RunSingleCommand without an intermediate quoting and
re-parsing step.

Reported-by: Andrey Pokrovskiy <[email protected]>
Brad King 9 vuotta sitten
vanhempi
sitoutus
1787269ef3

+ 7 - 0
Help/release/dev/cmake-E-time-quoting.rst

@@ -0,0 +1,7 @@
+cmake-E-time-quoting
+--------------------
+
+* The :manual:`cmake(1)` ``-E time`` command now properly passes arguments
+  with spaces or special characters through to the child process.  This
+  may break scripts that worked around the bug with their own extra
+  quoting or escaping.

+ 2 - 2
Source/cmcmd.cxx

@@ -554,7 +554,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
     // Clock command
     else if (args[1] == "time" && args.size() > 2)
       {
-      std::string command = cmJoin(cmMakeRange(args).advance(2), " ");
+      std::vector<std::string> command(args.begin()+2, args.end());
 
       clock_t clock_start, clock_finish;
       time_t time_start, time_finish;
@@ -562,7 +562,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
       time(&time_start);
       clock_start = clock();
       int ret =0;
-      cmSystemTools::RunSingleCommand(command.c_str(), 0, 0, &ret);
+      cmSystemTools::RunSingleCommand(command, 0, 0, &ret);
 
       clock_finish = clock();
       time(&time_finish);

+ 1 - 0
Tests/RunCMake/CommandLine/E_time-no-arg-result.txt

@@ -0,0 +1 @@
+1

+ 3 - 0
Tests/RunCMake/CommandLine/E_time-no-arg-stderr.txt

@@ -0,0 +1,3 @@
+^CMake Error: cmake version .*
+Usage: .* -E <command> \[arguments\.\.\.\]
+Available commands:

+ 3 - 0
Tests/RunCMake/CommandLine/E_time-stdout.txt

@@ -0,0 +1,3 @@
+^hello  world
+Elapsed time: [^
+]*$

+ 3 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -12,6 +12,9 @@ run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append)
 run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
 run_cmake_command(E_touch_nocreate-no-arg ${CMAKE_COMMAND} -E touch_nocreate)
 
+run_cmake_command(E_time ${CMAKE_COMMAND} -E time ${CMAKE_COMMAND} -E echo "hello  world")
+run_cmake_command(E_time-no-arg ${CMAKE_COMMAND} -E time)
+
 run_cmake_command(E___run_iwyu-no-iwyu ${CMAKE_COMMAND} -E __run_iwyu -- command-does-not-exist)
 run_cmake_command(E___run_iwyu-bad-iwyu ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist -- command-does-not-exist)
 run_cmake_command(E___run_iwyu-no--- ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist command-does-not-exist)