php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49139 proc_open requires double quotes
Submitted: 2009-08-03 13:09 UTC Modified: 2013-02-18 00:33 UTC
Votes:20
Avg. Score:3.9 ± 1.1
Reproduced:19 of 20 (95.0%)
Same Version:4 (21.1%)
Same OS:10 (52.6%)
From: david dot gausmann at measx dot com Assigned: pajoye (profile)
Status: No Feedback Package: Program Execution
PHP Version: 5.3.0 OS: win32 only - Windows XP SP3
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: david dot gausmann at measx dot com
New email:
PHP Version: OS:

 

 [2009-08-03 13:09 UTC] david dot gausmann at measx dot com
Description:
------------
The command, which shall be executed via proc_open, must be put in double quotes.
This bug was on functions like system, exec, ...
It seems not to be fixed on proc_open.

Reproduce code:
---------------
--- script1.php ---
<?php

  //Works fine
  echo "1.\r\n";
  system('"C:\php\php.exe" "C:\php\script2.php"');
  
  //FAILS!
  echo "2.\r\n";
  $arPipes = array();
  $rProcess = proc_open('"C:\php\php.exe" "C:\php\script2.php"', 
                  array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')), $arPipes);
  if($rProcess !== false)
  {
    $nExitCode = -1;
    do
    {
      while(!feof($arPipes[1]))
      {
        echo fread($arPipes[1], 1024);
        flush();
      }
      $array = proc_get_status($rProcess);
      if(!$array)
        break;
    } while($array['running']);
    fclose($arPipes[0]);
    fclose($arPipes[1]);
    fclose($arPipes[2]);
    proc_close($rProcess);
  }
  
  //Works fine (double quotes added)
  echo "3.\r\n";
  $arPipes = array();
  $rProcess = proc_open('""C:\php\php.exe" "C:\php\script2.php""', 
                  array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')), $arPipes);
  if($rProcess !== false)
  {
    $nExitCode = -1;
    do
    {
      while(!feof($arPipes[1]))
      {
        echo fread($arPipes[1], 1024);
        flush();
      }
      $array = proc_get_status($rProcess);
      if(!$array)
        break;
    } while($array['running']);
    fclose($arPipes[0]);
    fclose($arPipes[1]);
    fclose($arPipes[2]);
    proc_close($rProcess);
  }


?>
---script2.php---
<?php

  echo "Lorem ipsum\r\n";
  exit(0);

?>

Expected result:
----------------
1.
Lorem ipsum
2.
Lorem ipsum
3.

The third call of proc_open should fail, the second one should work.

Actual result:
--------------
1.
Lorem ipsum
2.
3.
Lorem ipsum

The second call of proc_open should fails, but the third one works.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-04-23 02:20 UTC] xandrani at googlemail dot com
Something similar fails for me... but even worse!

$Command = '"c:\program files\doxygen\bin\doxygen.exe" "C:\fred\doxyfile"'

$DescriptorSpecification = array
(
   0 => array('pipe', 'r'),
   1 => array('pipe', 'w'),
   2 => array('pipe', 'w')
);

$Resource = proc_open($Command, $DescriptorSpecification, $Pipes, null, $_ENV);

I get the error:
'c:\program' is not recognized as an internal or external command, operable program or batch file.

This works on exec() so not sure what's going on.
 [2010-04-23 02:22 UTC] xandrani at googlemail dot com
The double backward slashes didn't show correctly... but they are in my code.
 [2010-04-23 08:46 UTC] David dot Gausmann at measx dot com
This is the same problem as mine:

$Command = '""c:\program files\doxygen\bin\doxygen.exe" "C:\fred\doxyfile""';

$DescriptorSpecification = array
(
   0 => array('pipe', 'r'),
   1 => array('pipe', 'w'),
   2 => array('pipe', 'w')
);

$Resource = proc_open($Command, $DescriptorSpecification, $Pipes, null, $_ENV);

Works fine (because it has the nasty double quotes around everything).
 [2011-01-26 16:27 UTC] xc at ez dot no
Can someone speed up the fix? We have issue in our project based on this bug.

I assume second call in the example should work..

Related issue: https://issues.apache.org/jira/browse/ZETACOMP-48

Thanks.
 [2011-02-09 12:22 UTC] pajoye@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: pajoye
 [2011-02-09 12:22 UTC] pajoye@php.net
@xandrani at googlemail dot com

'"c:\program files\doxygen\bin\doxygen.exe" "C:\fred\doxyfile"'

works fine with proc_open.

For the initial comment and other:

<?php
echo PHP_EOL;
error_reporting(E_ALL|E_NOTICE);
$cmd = '"c:\\Program Files (x86)\\wcat\\wcutil.exe"';
$des = array
(
   0 => array('pipe', 'r'),
   1 => array('pipe', 'w'),
   2 => array('pipe', 'w')
);

$resource = proc_open($cmd, $des, $pipes, null, $_ENV);
var_dump(stream_get_contents($pipes[0]));
var_dump(stream_get_contents($pipes[1]));
var_dump(stream_get_contents($pipes[2]));

echo PHP_EOL;
echo "exec: " . PHP_EOL;
echo exec($cmd, $ret);
echo PHP_EOL;
print_r($ret);
echo PHP_EOL;

gives me:

string(0) ""
string(441) "Usage: wcutil [-s] [-d] [-x] [filename(*)]
    -s(imple)      Do not display CSV headers or average.
    -x(ml)         Xml output.
    -d(rophighlow) Drop highest and lowest path runs.

Column details:
    file   - output filename
    tps    - transactions per second
    kcpt   - kilocycles per transaction (aka 'path')
    bpt    - bytes per transaction
    cpu    - percent CPU utilization
    err    - count of any errors

"
string(0) ""

exec:

Array
(
    [0] => Usage: wcutil [-s] [-d] [-x] [filename(*)]
    [1] =>     -s(imple)      Do not display CSV headers or average.
    [2] =>     -x(ml)         Xml output.
    [3] =>     -d(rophighlow) Drop highest and lowest path runs.
    [4] =>
    [5] => Column details:
    [6] =>     file   - output filename
    [7] =>     tps    - transactions per second
    [8] =>     kcpt   - kilocycles per transaction (aka 'path')
    [9] =>     bpt    - bytes per transaction
    [10] =>     cpu    - percent CPU utilization
    [11] =>     err    - count of any errors
    [12] =>
)

which is correct.

Using 5.3.5 and 5.3-svn or trunk, on Windows 7/2003/2008.

Please try again and let me know if it still fails, using this exact sample (can 
be other command), or repost an example to reproduce it. I will also need to 
know which windows version you use.
 [2012-03-13 12:55 UTC] david dot gausmann at measx dot com
This bug is still present in PHP 5.4.

According to my previous example I've replaced the command line by the php interpreter and the reference to a script:

$cmd = '"d:\php-5.4.0\php.exe" "C:\xampp\htdocs\Neuer Ordner\script2.php"';

If I execute your script with the command line above I will get the following output:

-------------------------------------
D:\php-5.4.0>php -f C:\xampp\htdocs\testx.php

string(0) ""
string(0) ""
string(93) "Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträger
bezeichnung ist falsch.
"

exec:
Lorem ipsum
Array
(
    [0] => Lorem ipsum
)
-------------------------------------

If I move the file "script2.php" to an other location (without any spaces in it's path) then it works if I remove the double quotes from the parameter.

So the error only occurs if the parameters use double quotes, too.
In your example no parameters were used, so the error doesn't occured.


I've tested this with PHP 5.4 on Windows XP SP3.
 [2013-02-18 00:33 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.
 [2013-07-12 06:00 UTC] ku at digitaldolphins dot jp
I have same problem too, php 5.4.17 on Windows 7 SP1 x64.

I tried bypass_shell and it was ok: array("bypass_shell" => TRUE)

http://php.net/manual/en/function.proc-open.php

It seems that CMD.exe has trick. Check:

CMD.exe /?

or

http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-
us/cmd.mspx?mfr=true

---
Starts a new instance of the Windows command interpreter

CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
    [[/S] [/C | /K] string]

...

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
          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.

---

Check the bypass_shell code around CreateProcess. ext\standard\proc_open.c

 if (bypass_shell) {
  newprocok = CreateProcess(NULL, command, &security, &security, TRUE, 
dwCreateFlags, env.envp, cwd, &si, &pi);
 } else {
  spprintf(&command_with_cmd, 0, "%s /c %s", COMSPEC_NT, command);
  
  newprocok = CreateProcess(NULL, command_with_cmd, &security, &security, TRUE, 
dwCreateFlags, env.envp, cwd, &si, &pi);
  
  efree(command_with_cmd);
 }

---

We simulate the form "%s /c %s".

The result depends on the place where we have double quotes.

CMD /C "C:\Program Files\Internet Explorer\iexplore.exe" 
http://php.net
-> Ok

CMD /C "C:\Program Files\Internet Explorer\iexplore.exe" 
"http://php.net"
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
-> ERR

CMD /C ""C:\Program Files\Internet Explorer\iexplore.exe" 
"http://php.net""
-> Ok

---

Workarounds for now:
- Enclose entire command with double quotes.
- array("bypass_shell" => TRUE)
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Oct 19 12:01:27 2019 UTC