Browse Source

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 years ago
parent
commit
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
     // Clock command
     else if (args[1] == "time" && args.size() > 2)
     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;
       clock_t clock_start, clock_finish;
       time_t time_start, time_finish;
       time_t time_start, time_finish;
@@ -562,7 +562,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
       time(&time_start);
       time(&time_start);
       clock_start = clock();
       clock_start = clock();
       int ret =0;
       int ret =0;
-      cmSystemTools::RunSingleCommand(command.c_str(), 0, 0, &ret);
+      cmSystemTools::RunSingleCommand(command, 0, 0, &ret);
 
 
       clock_finish = clock();
       clock_finish = clock();
       time(&time_finish);
       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_rename-no-arg ${CMAKE_COMMAND} -E rename)
 run_cmake_command(E_touch_nocreate-no-arg ${CMAKE_COMMAND} -E touch_nocreate)
 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-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-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)
 run_cmake_command(E___run_iwyu-no--- ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist command-does-not-exist)