Eric Pouech : winedbg: Properly escape debuggee arguments.
Alexandre Julliard
julliard at winehq.org
Wed Dec 1 15:23:51 CST 2021
Module: wine
Branch: master
Commit: 94ca4be2a62cdb05adaee524084875b04b283afb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=94ca4be2a62cdb05adaee524084875b04b283afb
Author: Eric Pouech <eric.pouech at gmail.com>
Date: Wed Dec 1 15:30:17 2021 +0100
winedbg: Properly escape debuggee arguments.
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at 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;
}
More information about the wine-cvs
mailing list