Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:21801 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 4001 invoked by uid 1010); 6 Feb 2006 18:43:10 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 3984 invoked from network); 6 Feb 2006 18:43:10 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 6 Feb 2006 18:43:10 -0000 X-Host-Fingerprint: 64.233.184.199 wproxy.gmail.com Linux 2.4/2.6 Received: from ([64.233.184.199:62949] helo=wproxy.gmail.com) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id 92/62-45475-CB897E34 for ; Mon, 06 Feb 2006 13:43:09 -0500 Received: by wproxy.gmail.com with SMTP id i31so1085744wra for ; Mon, 06 Feb 2006 10:43:05 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=i/cTQhUgH44K/ZaDK/nJAo8raq2Fyh5tPqOcjV8z2DiFXU8JS/RF2lHexsngRz+w3bSc5J7OczDQsviPMZr761174f7bxmzeBwEgAVHQyGplpWVWDliAGHLmVSQpOgM9+bCfSFsD+BhqmzA8Fg5647NnFJG4BkZjAFH/pFruSKo= Received: by 10.54.122.10 with SMTP id u10mr1613521wrc; Mon, 06 Feb 2006 10:43:04 -0800 (PST) Received: by 10.54.153.2 with HTTP; Mon, 6 Feb 2006 10:43:04 -0800 (PST) Message-ID: <4e89b4260602061043n23ff9fd8n57fcc8d12d2e4839@mail.gmail.com> Date: Mon, 6 Feb 2006 13:43:04 -0500 To: Tim Starling Cc: internals@lists.php.net In-Reply-To: <89.3A.45475.11CB6E34@pb1.pair.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline References: <89.3A.45475.11CB6E34@pb1.pair.com> Subject: Re: [PHP-DEV] [PATCH] Bug #34671 Incorrect calling convention to cmd.exe From: kingwez@gmail.com (Wez Furlong) Is it possible that switching /S on will break existing scripts? If so, it's probably better to make the comspec setting a PHP .ini option that only the admin can change and allow /S to be set there. --Wez. On 2/5/06, Tim Starling wrote: > This patch is untested, my apologies for that. I don't have a working Vis= ual C++ environment in > which to compile PHP at the moment. I have, however, tested the concepts = involved. I can also > provide test cases and expected output if that would help. > > The problem is PHP's incorrect invocation of cmd.exe, which causes no end= of trouble to those > developing PHP applications on Windows systems. You can find many workaro= unds for it in the manual > comments, but a permanent, robust fix is actually quite simple, at least = for NT-based versions of > Windows. > > Here is an extract of the output of "help cmd" on Windows XP: > > CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF= ] > [[/S] [/C | /K] string] > > /C Carries out the command specified by string and then terminates > /K Carries out the command specified by string but remains > > [...] > > If /C or /K is specified, then the remainder of the command line after > the switch is processed as a command line, where the following logic is > used to process quote (") characters: > > 1. If all of the following conditions are met, then quote characters > on the command line are preserved: > > - no /S switch > - exactly two quote characters > - no special characters between the two quote characters, > where special is one of: &<>()@^| > - there are one or more whitespace characters between the > the two quote characters > - the string between the two quote characters is the name > of an executable file. > > 2. Otherwise, old behavior is to see if the first character is > a quote character and if so, strip the leading character and > remove the last quote character on the command line, preserving > any text after the last quote character. > > [end quote] > > This provides a simple, robust means to execute a command via cmd.exe: > > cmd.exe /s /c "...command goes here..." > > Otherwise, the programmer risks being plunged into a world of heuristic p= ain that only a Microsoft > developer could love. Some instructive examples: > > C:\>cmd /c "C:\Program Files\ImageMagick-6.2.6-Q16\convert.exe" > Version: ImageMagick 6.2.6 01/27/06 Q16 http://www.imagemagick.org > Copyright: Copyright (C) 1999-2006 ImageMagick Studio LLC > > Usage: convert.exe [options ...] file [ [options ...] file ...] [options = ...] file > [...] > > C:\>cmd /c "C:\Program Files\ImageMagick-6.2.6-Q16\convert.exe" -version > Version: ImageMagick 6.2.6 01/27/06 Q16 http://www.imagemagick.org > Copyright: Copyright (C) 1999-2006 ImageMagick Studio LLC > > C:\>cmd /c "C:\Program Files\ImageMagick-6.2.6-Q16\convert.exe" "some fil= e" > 'C:\Program' is not recognized as an internal or external command, > operable program or batch file. > > C:\>cd "C:\Program Files\ImageMagick-6.2.6-Q16" > > C:\Program Files\ImageMagick-6.2.6-Q16>cmd /c "convert source dest" > convert: unable to open image `source': No such file or directory. > convert: missing an image filename `dest'. > > C:\Program Files\ImageMagick-6.2.6-Q16>echo @echo G'day > "convert source= dest.bat" > > C:\Program Files\ImageMagick-6.2.6-Q16>cmd /c "convert source dest" > G'day > > > > Positively scary. /s restores sanity to the situation: > > C:\Program Files\ImageMagick-6.2.6-Q16>cmd /s /c "convert source dest" > convert: unable to open image `source': No such file or directory. > convert: missing an image filename `dest'. > > > Users of COMMAND.COM are not so blessed. There's no handling for double q= uotes at all, so if you > want to execute a program with spaces in the name, you just have to use t= he 8.3 alias. In my patch, > this is the responsibility of the application. > > C:\>command.com /s /c "echo hello" > Invalid switch > Bad command or file name > > The problem as it manifests itself in PHP was reported as Bug #34671, and= closed as bogus by a > trigger-happy admin. You can't work around it properly in application-lev= el code, because you can't > specify /s. > > -- Tim Starling > > > Index: TSRM/tsrm_win32.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > RCS file: /repository/TSRM/tsrm_win32.c,v > retrieving revision 1.28 > diff -u -r1.28 tsrm_win32.c > --- TSRM/tsrm_win32.c 1 Jan 2006 13:09:48 -0000 1.28 > +++ TSRM/tsrm_win32.c 6 Feb 2006 01:53:29 -0000 > @@ -209,8 +209,15 @@ > startup.hStdOutput =3D GetStdHandle(STD_OUTPUT_HANDLE); > } > > - cmd =3D (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof= (" /c ")); > - sprintf(cmd, "%s /c %s", TWG(comspec), command); > + if (GetVersion()<0x80000000) { > + /* NT calling convention: quotes around everything, /s to= disable heuristics */ > + cmd =3D (char*)malloc(strlen(command)+strlen(TWG(comspec)= )+sizeof(" /s /c \"\"")); > + sprintf(cmd, "%s /s /c \"%s\"", TWG(comspec), command); > + } else { > + /* 95/98/Me calling convention. Long names need to be con= verted to short names by the application. */ > + cmd =3D (char*)malloc(strlen(command)+strlen(TWG(comspec)= )+sizeof(" /c ")); > + sprintf(cmd, "%s /c %s", TWG(comspec), command); > + } > if (!CreateProcess(NULL, cmd, &security, &security, security.bInh= eritHandle, NORMAL_PRIORITY_CLASS, env, cwd, &startup, &process)) { > return NULL; > } > > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >