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 <wonder.mice@gmail.com>
This commit is contained in:
Brad King 2016-01-20 08:45:55 -05:00
parent d8bced813c
commit 1787269ef3
6 changed files with 19 additions and 2 deletions

View File

@ -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.

View File

@ -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);

View File

@ -0,0 +1 @@
1

View File

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

View File

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

View File

@ -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)