Module: wine Branch: master Commit: 94ca4be2a62cdb05adaee524084875b04b283afb URL: https://source.winehq.org/git/wine.git/?a=commit;h=94ca4be2a62cdb05adaee5240...
Author: Eric Pouech eric.pouech@gmail.com Date: Wed Dec 1 15:30:17 2021 +0100
winedbg: Properly escape debuggee arguments.
Signed-off-by: Eric Pouech eric.pouech@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
programs/winedbg/tgt_active.c | 106 +++++++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 21 deletions(-)
diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index 2a2af67debe..4bcd5ba659e 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -636,6 +636,88 @@ static BOOL dbg_start_debuggee(LPSTR cmdLine) return TRUE; }
+/*********************************************************************** + * dbg_build_command_line + * + * (converted from dlls/ntdll/unix/env.c) + * + * Build the command line of a process from the argv array. + * + * We must quote and escape characters so that the argv array can be rebuilt + * from the command line: + * - spaces and tabs must be quoted + * 'a b' -> '"a b"' + * - quotes must be escaped + * '"' -> '"' + * - if ''s are followed by a '"', they must be doubled and followed by '"', + * resulting in an odd number of '' followed by a '"' + * '"' -> '\"' + * '\"' -> '\\"' + * - ''s are followed by the closing '"' must be doubled, + * resulting in an even number of '' followed by a '"' + * ' ' -> '" \"' + * ' \' -> '" \\"' + * - ''s that are not followed by a '"' can be left as is + * 'a\b' == 'a\b' + * 'a\b' == 'a\b' + */ +static char *dbg_build_command_line( char **argv ) +{ + int len; + char **arg, *ret; + LPSTR p; + + len = 1; + for (arg = argv; *arg; arg++) len += 3 + 2 * strlen( *arg ); + if (!(ret = malloc( len ))) return NULL; + + p = ret; + for (arg = argv; *arg; arg++) + { + BOOL has_space, has_quote; + int i, bcount; + char *a; + + /* check for quotes and spaces in this argument (first arg is always quoted) */ + has_space = (arg == argv) || !**arg || strchr( *arg, ' ' ) || strchr( *arg, '\t' ); + has_quote = strchr( *arg, '"' ) != NULL; + + /* now transfer it to the command line */ + if (has_space) *p++ = '"'; + if (has_quote || has_space) + { + bcount = 0; + for (a = *arg; *a; a++) + { + if (*a == '\') bcount++; + else + { + if (*a == '"') /* double all the '\' preceding this '"', plus one */ + for (i = 0; i <= bcount; i++) *p++ = '\'; + bcount = 0; + } + *p++ = *a; + } + } + else + { + strcpy( p, *arg ); + p += strlen( p ); + } + if (has_space) + { + /* Double all the '' preceding the closing quote */ + for (i = 0; i < bcount; i++) *p++ = '\'; + *p++ = '"'; + } + *p++ = ' '; + } + if (p > ret) p--; /* remove last space */ + *p = 0; + return ret; +} + + void dbg_run_debuggee(const char* args) { if (args) @@ -807,35 +889,17 @@ enum dbg_start dbg_active_attach(int argc, char* argv[]) */ enum dbg_start dbg_active_launch(int argc, char* argv[]) { - int i, len; LPSTR cmd_line;
if (argc == 0) return start_error_parse;
- if (!(cmd_line = HeapAlloc(GetProcessHeap(), 0, len = 1))) - { - oom_leave: - dbg_printf("Out of memory\n"); - return start_error_init; - } - cmd_line[0] = '\0'; - - for (i = 0; i < argc; i++) - { - len += strlen(argv[i]) + 1; - if (!(cmd_line = HeapReAlloc(GetProcessHeap(), 0, cmd_line, len))) - goto oom_leave; - strcat(cmd_line, argv[i]); - cmd_line[len - 2] = ' '; - cmd_line[len - 1] = '\0'; - } - + cmd_line = dbg_build_command_line(argv); if (!dbg_start_debuggee(cmd_line)) { - HeapFree(GetProcessHeap(), 0, cmd_line); + free(cmd_line); return start_error_init; } - HeapFree(GetProcessHeap(), 0, dbg_last_cmd_line); + free(dbg_last_cmd_line); dbg_last_cmd_line = cmd_line; return start_ok; }