Handle quotes in command lines

Francois Gouget fgouget at free.fr
Thu Jan 10 21:10:39 CST 2002


On Thu, 10 Jan 2002, Uwe Bonnes wrote:

> >>>>> "Francois" == Francois Gouget <fgouget at free.fr> writes:
[...]
> Show me what lpCmdLine your test program passes to CreateProsess.

   The lpCmdline parameter is exactly as it was printed in my email.
This is why createp uses 'gets' to retrieve it:

main a\"b "c\"d\\" e

   That's if I run it as Winelib applications but if you run it in
Windows you will see:

H:\tests\cmdline\Debug>createp
Type the command to execute:
main a\"b "c\"d\\" e
CreateProcess returned: 1 error=0
GetCommandLine=[main a\"b "c\"d\\" e]
main -> argc=4
0 [main]
1 [a"b]
2 [c"d\]
3 [e]

   Which you will notice is identical.


> Are you
> sure createp code doesn't  misshandle things. Trying with my commandline
> test program, it looks right:
> : > wine -- cmdline.exe a\"b "c\"d\\" e
> : fixme:win32:PE_CreateModule Security directory ignored
> : "a"b c"d\ e"
> The first and last quotes are added by my program.

   If I run
   wine -- cmdline.exe a\"b "c\"d\\" e
   then it works. That's because in that case Wine knows the exact
command line and does not call BUILD_CommandLine. But now, modify your
caller.c program to pass the above arguments (or use my createp program)
and your will get:

   ""a\b "c\d\\"" e"

   In that case Wine:
 * added extra quotes. This is not wrong, but it is no better than
always removing extraneous quotes either
 * it also misinterpreted the \" between a and b. This is a bug.

   The difference between 'wine --' and CreateProcess is that in the
latter case Wine has to rebuild the command line from the argv array.


> E.g. tcsh chokes on your argument arangement (but tcsh isn't _the_
> reference:-):

   Strange. But I don't use C shells... Bash likes it just fine.


[...]
> Run a.exe of the tests appended and see the
> difference. Run against the DOS Shell in WinXX(/Vmware) to see what should
> happen.

   What your test program shows is that we currently loose extraneous
quotes. It is impossible to guess what the original command line is
from an argv array:
   argv[1]=ab can come from any of the following command lines (using
[] to delimit the command line):
   [ab]
   [ab ]
     trailing spaces can be significant
   ["ab"]
   [""ab]
   [""ab]
   [ab""]
   [ab"" ]
   [a"b]
      (in the above the " is not closed but it does not matter here)

   There are many more possibilities as soon as you have more than one
argument (one or more spaces between args, quotes for one, the other or
both, etc.). But I guess you get the idea.

   I really don't think that systematically adding quotes around
arguments is going to help. In fact I suspect that many applications
would not handle them correctly.

   The only reasonable I see to improve on the current code is to pass
the command line as it was specified to CreateProcess, directly to the
child. There two ways to do so: via an environment variable, or via the
wineserver. Using an environment variable is not very clean, especially
since either the parent or the child may not be Wine applications. To
make matters even more complex the child may not be a Wine process but
the grand-child may be one and then it should not use the command line
that was intended for its parent.
   Passing the command line via the wineserver code seems like the best
approach.

   Note, you should be able to find createp and my other tests program
in the wine-dev or wine-patches archives. I cannot give you the exact
URL because my internet connection is down but the following should help
you find it:

Date: Sun, 2 Sep 2001 19:37:43 -0700 (PDT)
From: Francois Gouget <fgouget at free.fr>
To: wine-devel at winehq.com
Subject: ' ' & '"' handling in the command line



--
Francois Gouget         fgouget at free.fr        http://fgouget.free.fr/
        War doesn't determine who's right.  War determines who's left.






More information about the wine-devel mailing list