I replied to Eli: > Eli Zaretskii wrote: > > > The test suite of the module 'system-quote' reveals that the '*' is also > > > special for CreateProcess on Windows and needs to be escaped > > > > What about '?'? Should we quote it as well? > > The statements that I have in the unit test > > check_one (interpreter, prog, "?"); > check_one (interpreter, prog, "foo?bar"); > > did not fail (on Windows XP).
The reason was that the unit test was not good enough. With more checks, I get a failure: expected: ??? received: sys expected: ???? received: sys expected: ????? received: sys for input = |???|: CreateProcess() command failed with status 1: .\test-system-quote-child.exe ??? for input = |????|: CreateProcess() command failed with status 1: .\test-system-quote-child.exe ???? for input = |?????|: CreateProcess() command failed with status 1: .\test-system-quote-child.exe ????? for input = |??????|: CreateProcess() command failed with status 3: .\test-system-quote-child.exe ?????? for input = |???????|: CreateProcess() command failed with status 3: .\test-system-quote-child.exe ??????? for input = |????????|: CreateProcess() command failed with status 3: .\test-system-quote-child.exe ???????? for input = |?????????|: CreateProcess() command failed with status 3: .\test-system-quote-child.exe ????????? FAIL: test-system-quote.sh Don't ask me why "????" and "?????" match "sys"... Anyway, the fix it to treat '?' like '*'. 2012-05-10 Bruno Haible <[email protected]> system-quote, execute, spawn-pipe: Escape '?' on Windows. * lib/system-quote.c (SHELL_SPECIAL_CHARS, CMD_SPECIAL_CHARS): Add the '?' character. * lib/w32spawn.h (SHELL_SPECIAL_CHARS): Likewise. * tests/test-system-quote-main.c (check_all): Check also strings like "??????????". Reported by Eli Zaretskii <[email protected]>. --- lib/system-quote.c.orig Fri May 11 01:38:41 2012 +++ lib/system-quote.c Fri May 11 01:24:24 2012 @@ -42,10 +42,15 @@ \" -> " \\\" -> \" \\\\\" -> \\" - - '*' characters may get expanded or lead to a failure with error code - ERROR_PATH_NOT_FOUND. + - '*', '?' characters may get expanded through wildcard expansion in the + callee: By default, in the callee, the initialization code before main() + takes the result of GetCommandLine(), wildcard-expands it, and passes it + to main(). The exceptions to this rule are: + - programs that inspect GetCommandLine() and ignore argv, + - mingw programs that have a global variable 'int _CRT_glob = 0;', + - Cygwin programs, when invoked from a Cygwin program. */ -# define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*" +# define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*?" # define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" /* Copies the quoted string to p and returns the number of bytes needed. @@ -112,7 +117,7 @@ double-quotes and the rest of the string inside double-quotes: %"var"%. This is guaranteed to not be a reference to an environment variable. */ -# define CMD_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037!%&'*+,;<=>[]^`{|}~" +# define CMD_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037!%&'*+,;<=>?[]^`{|}~" # define CMD_FORBIDDEN_CHARS "\n\r" /* Copies the quoted string to p and returns the number of bytes needed. --- lib/w32spawn.h.orig Fri May 11 01:38:41 2012 +++ lib/w32spawn.h Fri May 11 01:24:51 2012 @@ -115,10 +115,15 @@ \" -> " \\\" -> \" \\\\\" -> \\" - - '*' characters may get expanded or lead to a failure with error code - ERROR_PATH_NOT_FOUND. + - '*', '?' characters may get expanded through wildcard expansion in the + callee: By default, in the callee, the initialization code before main() + takes the result of GetCommandLine(), wildcard-expands it, and passes it + to main(). The exceptions to this rule are: + - programs that inspect GetCommandLine() and ignore argv, + - mingw programs that have a global variable 'int _CRT_glob = 0;', + - Cygwin programs, when invoked from a Cygwin program. */ -#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*" +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*?" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" static char ** prepare_spawn (char **argv) --- tests/test-system-quote-main.c.orig Fri May 11 01:38:41 2012 +++ tests/test-system-quote-main.c Fri May 11 01:37:43 2012 @@ -248,6 +248,15 @@ /* '?' would be interpreted as a wildcard character. */ check_one (interpreter, prog, "?"); + check_one (interpreter, prog, "??"); + check_one (interpreter, prog, "???"); + check_one (interpreter, prog, "????"); + check_one (interpreter, prog, "?????"); + check_one (interpreter, prog, "??????"); + check_one (interpreter, prog, "???????"); + check_one (interpreter, prog, "????????"); + check_one (interpreter, prog, "?????????"); + check_one (interpreter, prog, "??????????"); check_one (interpreter, prog, "foo?bar"); /* '^' would be interpreted in old /bin/sh, e.g. SunOS 4.1.4. */
