[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fixing Windows and DOS command line argument quoting

From: Daniel Colascione
Subject: Re: Fixing Windows and DOS command line argument quoting
Date: Mon, 25 Apr 2011 01:49:29 -0700
User-agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv: Gecko/20110303 Thunderbird/3.1.9

Hi Eli,

Thanks for taking a look at the patch.

On 4/24/11 11:41 PM, Eli Zaretskii wrote:
> Thanks.  I have 2 requests and a question.  The requests are:
>  . Please leave the `ms-dos' quoting as it was before.  (Your research
>    and blog are not valid for the MS-DOS, a.k.a. DJGPP, build of
>    Emacs, which uses its own private way of passing and decoding
>    command lines, bypassing MS runtime and OS facilities.  The
>    problems you mention in your blog do not exist in the MS-DOS
>    build.)  Please make the new quoting method effective for the
>    `windows-nt' case alone.

What happens when MS-DOS Emacs executes a non-DJGPP program?  Doesn't it
ever pass arguments through the command interpreter?  It's been a very
long time since I've used MS-DOS, and I don't know its command
interpreter's behavior differs from that of NT's cmd.exe.

>  . Please install this only on the trunk.  The emacs-23 branch should
>    not be destabilized by such experiments at this time.

Fair enough.

> My question is this: will cmdproxy need any changes to support this
> new kind of quoting, or does it already have everything that it needs?

Thanks for bringing up cmdproxy --- I hadn't considered its presence,
and for now, it's a fly in the ointment.

For concision, let's denote the CreateProcess/CommandLineToArgvW quoting
"level one quoting" and the requisite munging cmd.exe "level two
quoting".  w32proc.c already performs level one quoting, which is
sufficient because w32proc uses CreateProcess directly.

To execute a shell command with an argument Foo, we level-one-quote and
level-two-quote Foo, then run cmdproxy with Foo as an argument, allowing
w32proc to level-one-quote it (again).  cmdproxy (or more precisely, the
C runtime to which it's linked) level-one-dequotes the value supplied
with the /c option and runs the command interpreter, supplying that
argument as its command line.  The command interpreter
level-two-dequotes this command line, sending the result to the
indicated child program, which level-one-dequotes it and receives
exactly Foo.

This process would work well, except that cmdproxy contains an
optimization that causes it to bypass the command interpreter entirely
when the supplied command line doesn't appear to contain any shell
metacharacters.  In this case, cmdproxy passes the supplied command,
which is still level-two-quoted, directly to CreateProcess, causing the
child to attempt to level-one-dequote a level-two-quoted string, likely
yielding unexpected results.

Because shell-quote-argument doesn't know whether its return value will
be interpreted by cmd or by CreateProcess alone, we can't solve the
problem there.  Two solutions remain:

1. we can have cmdproxy level-two-dequote the supplied command line
before giving it to CreateProcess, or

2. we can remove optimization described above and have cmdproxy always
run the command interpreter.

I favor the second option: cmd starts very quickly, and we don't save
much time by bypassing it.  Adding level-two-dequoting to cmdproxy would
add additional complexity and duplicate logic already present in cmd
itself.  Also, the current strategy for deciding whether to run a
command directly or execute it via the shell doesn't sit right with me,
as it make the wrong decision when arguments happen to contain quoted
shell metacharacters.

Thanks again,
Daniel Colascione

Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]