From ba09bec5ecbff11c807eb72fbcb7fa4211e614e9 Mon Sep 17 00:00:00 2001 From: Alexey Edelev Date: Wed, 2 Oct 2024 13:08:42 +0200 Subject: [PATCH] Rework the argument escaping and wrapping in _qt_internal_create_command_script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the quote-based argument wrapping when generating the command line scripts for the tests. Apply the wrapping and escaping of the arguments right before writing the script with the following advanced rules: - if argument is already wrapped using quotes, skip wrapping - if argument is a CMake variable, skip wrapping - wrap the argument with qoutes otherwise The above should cover the most common usecases in centralized place when we generate the test wrapper scripts. Remove other ways we wrap arguments in other places, like square bracket wrapping in qt_internal_create_test_script. Change-Id: If287dd75d6fb36260b5cf8a687215bda9c9fc1c0 Reviewed-by: Tor Arne Vestbø Reviewed-by: Alexandru Croitor --- cmake/QtPublicTestHelpers.cmake | 16 ++++++++++++++-- cmake/QtTestHelpers.cmake | 17 ++++++----------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/cmake/QtPublicTestHelpers.cmake b/cmake/QtPublicTestHelpers.cmake index 771911c5d51..c7f48bfe88c 100644 --- a/cmake/QtPublicTestHelpers.cmake +++ b/cmake/QtPublicTestHelpers.cmake @@ -84,20 +84,32 @@ is not specified") set(command_echo "COMMAND_ECHO ${arg_COMMAND_ECHO}") endif() + set(command_escaped "") + foreach(command_arg IN LISTS arg_COMMAND) + if(NOT command_arg MATCHES "^\\\${[^}]+}$" AND NOT command_arg MATCHES "^\".+\"$") + string(REPLACE "\"" "\\\"" command_arg "${command_arg}") + string(APPEND command_escaped " \"${command_arg}\"") + else() + # Assume that all arguments that passed as escaped variables can be empty when + # unwrapped during the script execution. + string(APPEND command_escaped " ${command_arg}") + endif() + endforeach() + file(GENERATE OUTPUT "${arg_OUTPUT_FILE}" CONTENT "#!${CMAKE_COMMAND} -P # Qt generated command wrapper ${environment_extras} ${pre_run} -execute_process(COMMAND ${extra_runner} ${arg_COMMAND} +execute_process(COMMAND ${extra_runner} ${command_escaped} WORKING_DIRECTORY \"${arg_WORKING_DIRECTORY}\" ${command_echo} RESULT_VARIABLE result ) ${post_run} if(NOT result EQUAL 0) - string(JOIN \" \" full_command ${extra_runner} ${arg_COMMAND}) + string(JOIN \" \" full_command ${extra_runner} ${command_escaped}) message(FATAL_ERROR \"\${full_command} execution failed with exit code \${result}.\") endif()" ) diff --git a/cmake/QtTestHelpers.cmake b/cmake/QtTestHelpers.cmake index 7ca385b5f46..5bcbc60b598 100644 --- a/cmake/QtTestHelpers.cmake +++ b/cmake/QtTestHelpers.cmake @@ -948,7 +948,6 @@ for this function. Will be ignored") if(arg_ARGS) set(command_args ${arg_ARGS})# Avoid "${arg_ARGS}" usage and let cmake expand string to # semicolon-separated list - qt_internal_wrap_command_arguments(command_args) endif() if(TARGET ${arg_COMMAND}) @@ -974,13 +973,15 @@ for this function. Will be ignored") get_target_property(crosscompiling_emulator ${executable_name} CROSSCOMPILING_EMULATOR) if(NOT crosscompiling_emulator) set(crosscompiling_emulator "") - else() - qt_internal_wrap_command_arguments(crosscompiling_emulator) endif() endif() - _qt_internal_create_command_script(COMMAND "${crosscompiling_emulator} \${env_test_runner} \ -\"${executable_file}\" \${env_test_args} ${command_args}" + _qt_internal_create_command_script(COMMAND + ${crosscompiling_emulator} + "\${env_test_runner}" + "${executable_file}" + "\${env_test_args}" + ${command_args} OUTPUT_FILE "${arg_OUTPUT_FILE}" WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}" ENVIRONMENT ${arg_ENVIRONMENT} @@ -1044,12 +1045,6 @@ function(qt_internal_add_test_helper name) endfunction() -function(qt_internal_wrap_command_arguments argument_list) - list(TRANSFORM ${argument_list} REPLACE "^(.+)$" "[=[\\1]=]") - list(JOIN ${argument_list} " " ${argument_list}) - set(${argument_list} "${${argument_list}}" PARENT_SCOPE) -endfunction() - function(qt_internal_collect_command_environment out_path out_plugin_path) # Get path to /bin, as well as CMAKE_INSTALL_PREFIX/bin, and # combine them with the PATH environment variable.