-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proc_open(): Argument #2 ($descriptor_spec) must only contain arrays and streams [Descriptor item must be either an array or a File-Handle] #12655
Comments
Code to test different php versions.Just adjust the constant in the first line of code! <?php
const PHP_BINARIES = [ '/usr/bin/php7.4', '/usr/bin/php8.1', '/usr/bin/php8.2' ];
printf( "\n\n%s (%s): '%s'\n", PHP_BINARY, PHP_VERSION, implode( "' '", $argv ) );
$results = [];
if ( $argc === 1 )
{
foreach ( PHP_BINARIES as $binary )
{
$fatal = false;
$summary = false;
$last = null;
$results[ $binary ] [] = shell_exec( "$binary --version" );
$handle = popen(
sprintf(
"'%s' '%s' 1 2>&1",
$binary,
__FILE__
),
'r'
);
while ( $line = fgets( $handle, 500 ) )
{
if ( ! ( $summary || $fatal )
&& (
false
|| ( substr( $line, 0, 9 ) === "SUCCESS: " )
|| ( substr( $line, 0, 8 ) === "FAILED: " )
|| ( $summary = substr( $line, 0, 7 ) === "SUMMARY" )
) )
{
if ( ! $summary )
{
$results[ $binary ][] = $line;
}
}
echo $line;
$last = $line;
}
$results[ $binary ][] = sprintf( "rc=%s\n", pclose( $handle ) );
}
foreach ( $results as $binary => $result )
{
echo "\n\nRESULT for $binary;\n";
foreach ( $result as $line )
{
echo "$line";
}
}
exit();
}
const FD_I = 0; # stdin
const FD_O = 1; # stdout
const FD_E = 2; # stderr
const DESCRIPTORS
= [
FD_I => [ "pipe", "r" ], // stdin is a pipe that the child will read from
FD_O => [ "pipe", "w" ], // stdout is a pipe that the child will write to
FD_E => [ "pipe", "w" ], // stderr is a file to write to
];
function out( ?string $string )
{
static $stdout = STDOUT;
fwrite( $stdout, $string );
return $stdout;
}
if (\PHP_VERSION_ID < 80000) {
class ValueError extends Error
{
}
}
set_error_handler( function (
int $errno,
string $message
): bool {
throw new ValueError($message, $errno);
out( sprintf( "%d: %s\n", $errno, $message ) );
return true;
},
E_WARNING
);
$run = static function ( ?array $descriptorSpec, $comment ) use ( &$results )
{
static $test = 0;
$comment = sprintf( "%2s - %s", ++ $test, $comment );
out( "\nGoing to run: $comment\n" );
try
{
if ( $descriptorSpec !== null )
{
$proc = proc_open( "/bin/true", $descriptorSpec, $pipes );
}
else
{
$proc = proc_open( "/bin/true", DESCRIPTORS, $pipes );
}
if ( $proc === false )
{
$result = "FAILED";
}
else
{
foreach ( $pipes as $pipe )
{
fclose( $pipe );
}
$return_value = proc_close( $proc );
out( "rc=$return_value\n" );
$result = "SUCCESS";
}
}
catch ( ValueError $e )
{
printf( "%s: %s\n", get_class( $e ), $e->getMessage() );
var_dump( $e->getTraceAsString() );
$result = 'FAILED';
$comment .= ': ' . $e->getMessage();
}
$results[ $comment ] = $result;
out( sprintf( "%-8s %s\n", "$result:", $comment ) );
return $result === 'SUCCESS';
};
$descriptorSpec = DESCRIPTORS;
$run( $descriptorSpec, "clean array" ) || $run( $descriptorSpec = DESCRIPTORS, "re-run clean" );
$descriptorSpec = DESCRIPTORS;
foreach ( $descriptorSpec as $fd => $d )
{
;
}
$run( $descriptorSpec, "foreach by-val" ) || $run( $descriptorSpec = DESCRIPTORS, "re-run clean" );
$descriptorSpec = DESCRIPTORS;
foreach ( $descriptorSpec as $fd => &$d )
{
;
}
$run( $descriptorSpec, "foreach by-ref" ) || $run( $descriptorSpec = DESCRIPTORS, "re-run clean" );
$descriptorSpec = DESCRIPTORS;
array_walk( $descriptorSpec, static fn( $d ) => true );
$run( $descriptorSpec, "array_walk by-val" ) || $run( $descriptorSpec = DESCRIPTORS, "re-run clean" );
$descriptorSpec = DESCRIPTORS;
array_walk( $descriptorSpec, static fn( &$d ) => true );
$run( $descriptorSpec, "array_walk by-ref" ) || $run( $descriptorSpec = DESCRIPTORS, "re-run clean" );
$run( null, "original DESCRIPTORS" ) || $run( $descriptorSpec = DESCRIPTORS, "re-run clean" );
$descriptorSpec = DESCRIPTORS;
foreach ( DESCRIPTORS as $fd => $d )
{
;
}
$run( null, "foreach by-val DESCRIPTORS" ) || $run( $descriptorSpec, "re-run clean" );
foreach ( DESCRIPTORS as $fd => &$d )
{
;
}
$run( null, "foreach by-ref DESCRIPTORS" ) || $run( $descriptorSpec, "re-run clean" );
echo sprintf( "\n\nSUMMARY for php %s\n", PHP_VERSION );
array_walk( $results, static function ( $result, $comment )
{
out( sprintf( "%-8s %s\n", "$result:", $comment ) );
} );
fclose( out( null ) ); Output prints something that ends with the following summary:
|
martin-rueegg
changed the title
proc_open(): Descriptor item must be either an array or a File-Handle
proc_open(): Argument #2 ($descriptor_spec) must only contain arrays and streams [Descriptor item must be either an array or a File-Handle]
Nov 12, 2023
nielsdos
added
Extension: standard
Status: Verified
and removed
Status: Needs Triage
labels
Nov 12, 2023
Can reproduce. Missing a |
nielsdos
added a commit
to nielsdos/php-src
that referenced
this issue
Nov 12, 2023
… the descriptor array
nielsdos
added a commit
that referenced
this issue
Nov 13, 2023
* PHP-8.2: Fix GH-12655: proc_open() does not take into account references in the descriptor array
nielsdos
added a commit
that referenced
this issue
Nov 13, 2023
* PHP-8.3: Fix GH-12655: proc_open() does not take into account references in the descriptor array
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
The following code:
Resulted in this output (v 7.4):
Resulted in this output (v 8.x):
But I expected this output instead:
If you leave away the "by-reference-amphersand", the code will succeed!
Since 3v4l.org does not support
proc_open
, I've created a test code which I'll post in the first comment.PHP Version
PHP 7.4.33 / 8.1.25 / 8.2.12
Operating System
Ubuntu 22.04.3 LTS
The text was updated successfully, but these errors were encountered: