[PATCH] kernel32: Allow double quote style escape in argv
Brendan McGrath
brendan at redmandi.com
Tue Feb 26 02:39:25 CST 2019
In Windows, two quotes together (within outer quotes) represents a
single quote (with the first quote acting as an escape character)
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46721
Signed-off-by: Brendan McGrath <brendan at redmandi.com>
---
dlls/kernel32/process.c | 17 +++++++++++++----
dlls/kernel32/tests/process.c | 7 ++++---
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index ad257a054e4..89b561ef811 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1505,9 +1505,13 @@ static char **build_argv( const UNICODE_STRING *cmdlineW, int reserved )
/* '\', count them */
bcount++;
} else if ((*s=='"') && ((bcount & 1)==0)) {
- /* unescaped '"' */
- in_quotes=!in_quotes;
- bcount=0;
+ if (in_quotes && s[1] == '"') {
+ s++;
+ } else {
+ /* unescaped '"' */
+ in_quotes=!in_quotes;
+ bcount=0;
+ }
} else {
/* a regular character */
bcount=0;
@@ -1551,7 +1555,12 @@ static char **build_argv( const UNICODE_STRING *cmdlineW, int reserved )
*/
d-=bcount/2;
s++;
- in_quotes=!in_quotes;
+ if(in_quotes && *s == '"') {
+ *d++='"';
+ s++;
+ } else {
+ in_quotes=!in_quotes;
+ }
} else {
/* Preceded by an odd number of '\', this is half that
* number of '\' followed by a '"'
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index fe68d28e914..f62f8fb0ba1 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -896,7 +896,7 @@ static void test_CommandLine(void)
/* the basics */
get_file_name(resfile);
- sprintf(buffer, "\"%s\" tests/process.c dump \"%s\" \"C:\\Program Files\\my nice app.exe\"", selfname, resfile);
+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\" \"C:\\Program Files\\my nice app.exe\" \"\"\"\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
/* wait for child to terminate */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
@@ -905,9 +905,10 @@ static void test_CommandLine(void)
CloseHandle(info.hThread);
CloseHandle(info.hProcess);
- okChildInt("Arguments", "argcA", 5);
+ okChildInt("Arguments", "argcA", 6);
okChildString("Arguments", "argvA4", "C:\\Program Files\\my nice app.exe");
- okChildString("Arguments", "argvA5", NULL);
+ okChildString("Arguments", "argvA5", "\"");
+ okChildString("Arguments", "argvA6", NULL);
okChildString("Arguments", "CommandLineA", buffer);
release_memory();
DeleteFileA(resfile);
--
2.17.1
More information about the wine-devel
mailing list