From 42fa954849da670f56043766d1a17a9f36ceb94f Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Fri, 16 Jan 2015 22:21:02 +1100 Subject: subprocess-win: Always quote argv[0] If the program name isn't quoted and the .exe it refers to isn't found, CreateProcess will add the program arguments to the program name and continue searching, so for "program arg1 arg2", CreateProcess would try "program.exe", "program arg1.exe", then "program arg1 arg2.exe". This behaviour is weird and not really desirable, so prevent it by always quoting the program name. When quoting argv[0], escape sequences shouldn't be used. msvcrt, .NET and CommandLineToArgvW all treat argv[0] literally and end it on the trailing quote, without processing escape sequences. --- osdep/subprocess-win.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'osdep') diff --git a/osdep/subprocess-win.c b/osdep/subprocess-win.c index fc5db081f8..211f407db1 100644 --- a/osdep/subprocess-win.c +++ b/osdep/subprocess-win.c @@ -83,12 +83,14 @@ static void write_arg(bstr *cmdline, char *arg) // Convert an array of arguments to a properly escaped command-line string static wchar_t *write_cmdline(void *ctx, char **argv) { + // argv[0] should always be quoted. Otherwise, arguments may be interpreted + // as part of the program name. Also, it can't contain escape sequences. bstr cmdline = {0}; + bstr_xappend_asprintf(NULL, &cmdline, "\"%s\"", argv[0]); - for (int i = 0; argv[i]; i++) { + for (int i = 1; argv[i]; i++) { + bstr_xappend(NULL, &cmdline, bstr0(" ")); write_arg(&cmdline, argv[i]); - if (argv[i + 1]) - bstr_xappend(NULL, &cmdline, bstr0(" ")); } wchar_t *wcmdline = mp_from_utf8(ctx, cmdline.start); -- cgit v1.2.3