Req #81493 [Opn]: shell_exec() should get a `int &$result_code = null` argument
| From: | nikic@php.net | Date: | Fri, 01 Oct 2021 15:21:33 +0000 |
| Subject: | Req #81493 [Opn]: shell_exec() should get a `int &$result_code = null` argument | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-236973@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=81493&edit=1
ID: 81493
Updated by: nikic@php.net
Reported by: divinity76 at gmail dot com
Summary: shell_exec() should get a
int &$result_code = null
argument
Status: Open
Type: Feature/Change Request
Package: Unknown/Other Function
PHP Version: Next Minor Version
Block user comment: N
Private report: N
New Comment:
The docs for shell_exec() say:
> On Windows, the underlying pipe is opened in text mode which can cause the function to fail for
> binary output. Consider to use popen() instead for such cases.
So it wouldn't be binary safe either...
It's funny how we have so many of these functions and they all kinda suck.
Previous Comments:
------------------------------------------------------------------------
[2021-10-01 15:17:13] divinity76 at gmail dot com
actually scratch the exec() workaround, turns out that exec() is non-binary-safe and can't do
shell_exec()'s job at all (in cases where binary safety is important)
- with exec() it is impossible to differentiate between programs printing "foo" and
"foo\n"
------------------------------------------------------------------------
[2021-10-01 15:08:10] divinity76 at gmail dot com
actually the implode() workaround is non-binary-safe, take for example:
<?php
declare(strict_types=1);
$cmd= "php -r ".escapeshellarg('echo
'.var_export("\n",true).";");
exec($cmd,$output,$ret);
$output=implode("\n",$output);
var_dump($output);
?>
it prints emptystring, not a string containing a newline, sooo data corruption
------------------------------------------------------------------------
[2021-10-01 15:01:05] divinity76 at gmail dot com
@requinix to use exec() for the same task as shell_exec(), you'll have to (ab)use implode()
like
exec($cmd,$output,$ret);
$output=implode("\n", $output);
and to use system() for the same job, you'd have to (ab)use ob_* like
ob_start();
system($cmd,$ret);
$output=ob_get_clean();
same for passthru()
as it stands now, if you want to do a shell_exec while also getting the os-level return value,
you'll have to do a exec()+implode() workaround.. there would be no need for workarounds if
shell_exec supported $result_code
------------------------------------------------------------------------
[2021-10-01 14:37:57] requinix@php.net
If you want a status code then why not use exec() or system()? Do we really need to make all three
functions even *more* similar to each other?
------------------------------------------------------------------------
[2021-10-01 13:52:37] divinity76 at gmail dot com
Description:
------------
doing exactly the same as the $result_code argument for system() and passthru() and exec()
Test script:
---------------
<?php
$result_code=null;
shell_exec(bin2hex(random_bytes(10))." 2>&1", $result_code);
var_dump($result_code);
Expected result:
----------------
platform-specific expected result, but at least on Linux one would expect:
int(127)
Actual result:
--------------
PHP Warning: shell_exec() expects exactly 1 parameter, 2 given in /home/hansh/foo3.php on line 3
NULL
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81493&edit=1