From 750ab50433836079f3dc7068e765f542e7aca179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 6 May 2019 00:02:57 +0300 Subject: [PATCH] wrappers: Consistently quote all arguments when calling spawn or creating a command line --- wrappers/clang-target-wrapper.c | 9 +++---- wrappers/native-wrapper.h | 17 +++++++++---- wrappers/windres-wrapper.c | 42 ++++++++++++++++----------------- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/wrappers/clang-target-wrapper.c b/wrappers/clang-target-wrapper.c index 87b5507..95a5d28 100644 --- a/wrappers/clang-target-wrapper.c +++ b/wrappers/clang-target-wrapper.c @@ -75,12 +75,13 @@ static void filter_stderr(char *buf, int n) { } static int exec_filtered(const TCHAR **argv) { + for (int i = 0; argv[i]; i++) + argv[i] = escape(argv[i]); int len = 1; for (int i = 0; argv[i]; i++) len += _tcslen(argv[i]) + 1; TCHAR *cmdline = malloc(len * sizeof(*cmdline)); int pos = 0; - // On Windows, the arguments are already quoted and escaped properly. for (int i = 0; argv[i]; i++) { _tcscpy(&cmdline[pos], argv[i]); pos += _tcslen(argv[i]); @@ -165,7 +166,7 @@ int _tmain(int argc, TCHAR* argv[]) { int arg = 0; if (getenv("CCACHE")) exec_argv[arg++] = _T("ccache"); - exec_argv[arg++] = escape(concat(dir, _T(CLANG))); + exec_argv[arg++] = concat(dir, _T(CLANG)); // If changing this wrapper, change clang-target-wrapper.sh accordingly. if (!_tcscmp(exe, _T("clang++")) || !_tcscmp(exe, _T("g++")) || !_tcscmp(exe, _T("c++"))) @@ -204,7 +205,7 @@ int _tmain(int argc, TCHAR* argv[]) { exec_argv[arg++] = _T("-Qunused-arguments"); for (int i = 1; i < argc; i++) - exec_argv[arg++] = escape(argv[i]); + exec_argv[arg++] = argv[i]; exec_argv[arg] = NULL; if (arg > max_arg) { @@ -222,7 +223,7 @@ int _tmain(int argc, TCHAR* argv[]) { if (!_tcscmp(argv[i], _T("-v"))) return exec_filtered(exec_argv); - int ret = _tspawnvp(_P_WAIT, exec_argv[0], exec_argv); + int ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv); if (ret == -1) { _tperror(exec_argv[0]); return 1; diff --git a/wrappers/native-wrapper.h b/wrappers/native-wrapper.h index c5e4adc..7cfdf23 100644 --- a/wrappers/native-wrapper.h +++ b/wrappers/native-wrapper.h @@ -56,8 +56,8 @@ typedef char TCHAR; #define TS "%s" #endif -static TCHAR *escape(const TCHAR *str) { #ifdef _WIN32 +static TCHAR *escape(const TCHAR *str) { TCHAR *out = malloc((_tcslen(str) * 2 + 3) * sizeof(*out)); TCHAR *ptr = out; int i; @@ -82,11 +82,20 @@ static TCHAR *escape(const TCHAR *str) { *ptr++ = '"'; *ptr++ = '\0'; return out; -#else - return _tcsdup(str); -#endif } +static int _tspawnvp_escape(int mode, const TCHAR *filename, const TCHAR * const *argv) { + int num_args = 0; + while (argv[num_args]) + num_args++; + const TCHAR **escaped_argv = malloc(num_args * sizeof(*escaped_argv)); + for (int i = 0; argv[i]; i++) + escaped_argv[i] = escape(argv[i]); + escaped_argv[num_args] = NULL; + return _tspawnvp(mode, filename, escaped_argv); +} +#endif + static TCHAR *concat(const TCHAR *prefix, const TCHAR *suffix) { int prefixlen = _tcslen(prefix); int suffixlen = _tcslen(suffix); diff --git a/wrappers/windres-wrapper.c b/wrappers/windres-wrapper.c index 8e0d07b..3622289 100644 --- a/wrappers/windres-wrapper.c +++ b/wrappers/windres-wrapper.c @@ -37,7 +37,7 @@ #ifdef _WIN32 #else -#define _tspawnvp _spawnvp +#define _tspawnvp_escape _spawnvp #include #include @@ -287,21 +287,21 @@ int _tmain(int argc, TCHAR* argv[]) { int arg = 0; if (!_tcscmp(input_format, _T("rc"))) { - exec_argv[arg++] = escape(concat(dir, CC)); + exec_argv[arg++] = concat(dir, CC); exec_argv[arg++] = _T("-E"); for (int i = 0; i < nb_cpp_options; i++) - exec_argv[arg++] = escape(cpp_options[i]); + exec_argv[arg++] = cpp_options[i]; exec_argv[arg++] = _T("-xc"); exec_argv[arg++] = _T("-DRC_INVOKED=1"); - exec_argv[arg++] = escape(input); + exec_argv[arg++] = input; exec_argv[arg++] = _T("-o"); - exec_argv[arg++] = escape(preproc_rc); + exec_argv[arg++] = preproc_rc; exec_argv[arg] = NULL; check_num_args(arg, max_arg); if (verbose) print_argv(exec_argv); - int ret = _tspawnvp(_P_WAIT, exec_argv[0], exec_argv); + int ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv); if (ret == -1) { _tperror(exec_argv[0]); return 1; @@ -312,25 +312,25 @@ int _tmain(int argc, TCHAR* argv[]) { } arg = 0; - exec_argv[arg++] = escape(concat(dir, _T("llvm-rc"))); + exec_argv[arg++] = concat(dir, _T("llvm-rc")); for (int i = 0; i < nb_rc_options; i++) - exec_argv[arg++] = escape(rc_options[i]); + exec_argv[arg++] = rc_options[i]; exec_argv[arg++] = _T("-I"); - exec_argv[arg++] = escape(inputdir); - exec_argv[arg++] = escape(preproc_rc); + exec_argv[arg++] = inputdir; + exec_argv[arg++] = preproc_rc; exec_argv[arg++] = _T("-c"); exec_argv[arg++] = codepage; exec_argv[arg++] = _T("-fo"); if (!_tcscmp(output_format, _T("res"))) - exec_argv[arg++] = escape(output); + exec_argv[arg++] = output; else - exec_argv[arg++] = escape(res); + exec_argv[arg++] = res; exec_argv[arg] = NULL; check_num_args(arg, max_arg); if (verbose) print_argv(exec_argv); - ret = _tspawnvp(_P_WAIT, exec_argv[0], exec_argv); + ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv); if (ret == -1) { _tperror(exec_argv[0]); return 1; @@ -346,16 +346,16 @@ int _tmain(int argc, TCHAR* argv[]) { // All done } else if (!_tcscmp(output_format, _T("coff"))) { arg = 0; - exec_argv[arg++] = escape(concat(dir, _T("llvm-cvtres"))); - exec_argv[arg++] = escape(res); + exec_argv[arg++] = concat(dir, _T("llvm-cvtres")); + exec_argv[arg++] = res; exec_argv[arg++] = concat(_T("-machine:"), machine); - exec_argv[arg++] = escape(concat(_T("-out:"), output)); + exec_argv[arg++] = concat(_T("-out:"), output); exec_argv[arg] = NULL; check_num_args(arg, max_arg); if (verbose) print_argv(exec_argv); - int ret = _tspawnvp(_P_WAIT, exec_argv[0], exec_argv); + int ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv); if (ret == -1) { _tperror(exec_argv[0]); return 1; @@ -369,16 +369,16 @@ int _tmain(int argc, TCHAR* argv[]) { error(basename, _T("invalid output format: `"TS"'"), output_format); } } else if (!_tcscmp(input_format, _T("res"))) { - exec_argv[arg++] = escape(concat(dir, _T("llvm-cvtres"))); - exec_argv[arg++] = escape(input); + exec_argv[arg++] = concat(dir, _T("llvm-cvtres")); + exec_argv[arg++] = input; exec_argv[arg++] = concat(_T("-machine:"), machine); - exec_argv[arg++] = escape(concat(_T("-out:"), output)); + exec_argv[arg++] = concat(_T("-out:"), output); exec_argv[arg] = NULL; check_num_args(arg, max_arg); if (verbose) print_argv(exec_argv); - int ret = _tspawnvp(_P_WAIT, exec_argv[0], exec_argv); + int ret = _tspawnvp_escape(_P_WAIT, exec_argv[0], exec_argv); if (ret == -1) { _tperror(exec_argv[0]); return 1;