diff options
Diffstat (limited to 'ext/standard')
| -rw-r--r-- | ext/standard/image.c | 6 | ||||
| -rw-r--r-- | ext/standard/tests/streams/proc_open_bug51800.phpt | 95 | ||||
| -rw-r--r-- | ext/standard/tests/streams/proc_open_bug51800_right.phpt | 78 | ||||
| -rw-r--r-- | ext/standard/tests/streams/proc_open_bug51800_right2.phpt | 84 | ||||
| -rw-r--r-- | ext/standard/tests/streams/proc_open_bug60120.phpt | 71 | ||||
| -rw-r--r-- | ext/standard/tests/streams/proc_open_bug64438.phpt | 70 |
6 files changed, 401 insertions, 3 deletions
diff --git a/ext/standard/image.c b/ext/standard/image.c index 02246c6268..f1910d2191 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -365,8 +365,8 @@ static unsigned short php_read2(php_stream * stream TSRMLS_DC) { unsigned char a[2]; - /* just return 0 if we hit the end-of-file */ - if((php_stream_read(stream, a, sizeof(a))) <= 0) return 0; + /* return 0 if we couldn't read enough data */ + if((php_stream_read(stream, a, sizeof(a))) < sizeof(a)) return 0; return (((unsigned short)a[0]) << 8) + ((unsigned short)a[1]); } @@ -646,7 +646,7 @@ static struct gfxinfo *php_handle_jpc(php_stream * stream TSRMLS_DC) #endif result->channels = php_read2(stream TSRMLS_CC); /* Csiz */ - if (result->channels < 0 || result->channels > 256) { + if (result->channels == 0 && php_stream_eof(stream) || result->channels > 256) { efree(result); return NULL; } diff --git a/ext/standard/tests/streams/proc_open_bug51800.phpt b/ext/standard/tests/streams/proc_open_bug51800.phpt new file mode 100644 index 0000000000..53cafd8555 --- /dev/null +++ b/ext/standard/tests/streams/proc_open_bug51800.phpt @@ -0,0 +1,95 @@ +--TEST-- +Bug #51800 proc_open on Windows hangs forever +--SKIPIF-- +<?php + echo 'skip expected to fail or take too long'; + if (getenv("SKIP_SLOW_TESTS")) { + die("skip slow test"); + } +?> +--XFAIL-- +pipes have to be read/written simultaneously +--FILE-- +<?php +/* This is the wrong way to do it. The parent will block till it has read all the STDIN. +The smaller the pipe buffer is, the longer it will take. It might even pass at the end, +after taking inappropriately long. Pipes have to be read simultaneously in smaller chunks, +so then the pipe buffer is emptied more often and the child has chance to continue its +write. The behaviour might look some better if write/read in a separate thread, however +this is much more resource greedy and complexer to integrate into the user script. */ + +$callee = dirname(__FILE__) . "/process_proc_open_bug51800.php"; +$php = PHP_BINARY; +$cmd = "$php $callee"; + +$status; +$stdout = ""; +$stderr = ""; +$pipes = array(); + +$descriptors = array( + 0 => array("pipe", "rb"), // stdin + 1 => array("pipe", "wb"), // stdout + 2 => array("pipe", "wb") // stderr + ); + +/* create the proc file */ +$r = file_put_contents($callee, '<?php + +$how_much = 10000; + +$data0 = str_repeat("a", $how_much); +$data1 = str_repeat("b", $how_much); +fwrite(STDOUT, $data0); +fwrite(STDERR, $data1); + +exit(0); +'); + +if (!$r) { + die("couldn't create helper script '$callee'"); +} + +$process = proc_open($cmd, $descriptors, $pipes); + +if (is_resource($process)) +{ + fclose($pipes[0]); + + while (!feof($pipes[1])) + $stdout .= fread($pipes[1], 1024); + fclose($pipes[1]); + + while (!feof($pipes[2])) + $stderr .= fread($pipes[2], 1024); + fclose($pipes[2]); + + $status = proc_close($process); +} + +var_dump(array( + "status" => $status, + "stdout" => $stdout, + "stderr" => $stderr, +), strlen($stdout), strlen($stderr)); + +?> +===DONE=== +--CLEAN-- +<?php +$callee = dirname(__FILE__) . "/process_proc_open_bug51800.php"; +unlink($callee); +?> +--EXPECTF-- +array(3) { + ["status"]=> + int(0) + ["stdout"]=> + string(10000) "a%s" + ["stderr"]=> + string(10000) "b%s" +} +int(10000) +int(10000) +===DONE=== + diff --git a/ext/standard/tests/streams/proc_open_bug51800_right.phpt b/ext/standard/tests/streams/proc_open_bug51800_right.phpt new file mode 100644 index 0000000000..b14fed2e5d --- /dev/null +++ b/ext/standard/tests/streams/proc_open_bug51800_right.phpt @@ -0,0 +1,78 @@ +--TEST-- +Bug #51800 proc_open on Windows hangs forever, the right way to do it +--FILE-- +<?php +$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right.php"; +$php = PHP_BINARY; +$cmd = "$php $callee"; + +$status; +$stdout = ""; +$stderr = ""; +$pipes = array(); + +$descriptors = array( + 0 => array("pipe", "rb"), // stdin + 1 => array("pipe", "wb"), // stdout + 2 => array("pipe", "wb") // stderr + ); + +/* create the proc file */ +$r = file_put_contents($callee, '<?php + +$how_much = 10000; + +$data0 = str_repeat("a", $how_much); +$data1 = str_repeat("b", $how_much); +fwrite(STDOUT, $data0); +fwrite(STDERR, $data1); + +exit(0); +'); + +if (!$r) { + die("couldn't create helper script '$callee'"); +} + +$process = proc_open($cmd, $descriptors, $pipes); + +if (is_resource($process)) +{ + fclose($pipes[0]); + + while (!feof($pipes[1]) || !feof($pipes[2])) { + $stdout .= fread($pipes[1], 1024); + $stderr .= fread($pipes[2], 1024); + } + fclose($pipes[1]); + fclose($pipes[2]); + + $status = proc_close($process); +} + +var_dump(array( + "status" => $status, + "stdout" => $stdout, + "stderr" => $stderr, +), strlen($stdout), strlen($stderr)); + +?> +===DONE=== +--CLEAN-- +<?php +$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right.php"; +unlink($callee); +?> +--EXPECTF-- +array(3) { + ["status"]=> + int(0) + ["stdout"]=> + string(10000) "a%s" + ["stderr"]=> + string(10000) "b%s" +} +int(10000) +int(10000) +===DONE=== + diff --git a/ext/standard/tests/streams/proc_open_bug51800_right2.phpt b/ext/standard/tests/streams/proc_open_bug51800_right2.phpt new file mode 100644 index 0000000000..1e742745c1 --- /dev/null +++ b/ext/standard/tests/streams/proc_open_bug51800_right2.phpt @@ -0,0 +1,84 @@ +--TEST-- +Bug #51800 proc_open on Windows hangs forever, the right way to do it with more data +--FILE-- +<?php +$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right2.php"; +$php = PHP_BINARY; +$cmd = "$php $callee"; + +$status; +$stdout = ""; +$stderr = ""; +$pipes = array(); + +$descriptors = array( + 0 => array("pipe", "rb"), // stdin + 1 => array("pipe", "wb"), // stdout + 2 => array("pipe", "wb") // stderr + ); + +/* create the proc file */ +$r = file_put_contents($callee, '<?php +$how_much = 1000000; + +$data0 = str_repeat("a", $how_much); +$data1 = str_repeat("b", $how_much); +$i0 = $i1 = 0; +$step = 1024; + +while ($i0 < strlen($data0) && $i1 < strlen($data1)) { + fwrite(STDOUT, substr($data0, $i0, $step)); + fwrite(STDERR, substr($data1, $i1, $step)); + $i0 += $step; + $i1 += $step; +} + +exit(0); +'); + +if (!$r) { + die("couldn't create helper script '$callee'"); +} + +$process = proc_open($cmd, $descriptors, $pipes); + +if (is_resource($process)) +{ + fclose($pipes[0]); + + while (!feof($pipes[1]) || !feof($pipes[2])) { + $stdout .= fread($pipes[1], 1024); + $stderr .= fread($pipes[2], 1024); + } + fclose($pipes[1]); + fclose($pipes[2]); + + $status = proc_close($process); +} + +var_dump(array( + "status" => $status, + "stdout" => $stdout, + "stderr" => $stderr, +), strlen($stdout), strlen($stderr)); + +?> +===DONE=== +--CLEAN-- +<?php +$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right2.php"; +unlink($callee); +?> +--EXPECTF-- +array(3) { + ["status"]=> + int(0) + ["stdout"]=> + string(1000000) "a%s" + ["stderr"]=> + string(1000000) "b%s" +} +int(1000000) +int(1000000) +===DONE=== + diff --git a/ext/standard/tests/streams/proc_open_bug60120.phpt b/ext/standard/tests/streams/proc_open_bug60120.phpt new file mode 100644 index 0000000000..8768257a2e --- /dev/null +++ b/ext/standard/tests/streams/proc_open_bug60120.phpt @@ -0,0 +1,71 @@ +--TEST-- +Bug #60120 proc_open hangs with stdin/out with 2048+ bytes +--FILE-- +<?php +error_reporting(E_ALL); + +if (substr(PHP_OS, 0, 3) == 'WIN') { + $cmd = PHP_BINARY . ' -n -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"'; +} else { + $cmd = PHP_BINARY . ' -n -r \'fwrite(STDOUT, $in = file_get_contents("php://stdin")); fwrite(STDERR, $in);\''; +} +$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); +$stdin = str_repeat('*', 1024 * 16) . '!'; +$stdin = str_repeat('*', 2049 ); + +$options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false)); +$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options); + +foreach ($pipes as $pipe) { + stream_set_blocking($pipe, false); +} +$writePipes = array($pipes[0]); +$stdinLen = strlen($stdin); +$stdinOffset = 0; + +unset($pipes[0]); + +while ($pipes || $writePipes) { + $r = $pipes; + $w = $writePipes; + $e = null; + $n = stream_select($r, $w, $e, 60); + + if (false === $n) { + break; + } elseif ($n === 0) { + proc_terminate($process); + + } + if ($w) { + $written = fwrite($writePipes[0], (binary)substr($stdin, $stdinOffset), 8192); + if (false !== $written) { + $stdinOffset += $written; + } + if ($stdinOffset >= $stdinLen) { + fclose($writePipes[0]); + $writePipes = null; + } + } + + foreach ($r as $pipe) { + $type = array_search($pipe, $pipes); + $data = fread($pipe, 8192); + var_dump($data); + if (false === $data || feof($pipe)) { + fclose($pipe); + unset($pipes[$type]); + } + } +} + + +?> +===DONE=== +--EXPECTF-- +string(2049) "%s" +string(2049) "%s" +string(0) "" +string(0) "" +===DONE=== + diff --git a/ext/standard/tests/streams/proc_open_bug64438.phpt b/ext/standard/tests/streams/proc_open_bug64438.phpt new file mode 100644 index 0000000000..b3857d09d4 --- /dev/null +++ b/ext/standard/tests/streams/proc_open_bug64438.phpt @@ -0,0 +1,70 @@ +--TEST-- +Bug #64438 proc_open hangs with stdin/out with 4097+ bytes +--FILE-- +<?php + +error_reporting(E_ALL); + +if (substr(PHP_OS, 0, 3) == 'WIN') { + $cmd = PHP_BINARY . ' -n -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"'; +} else { + $cmd = PHP_BINARY . ' -n -r \'fwrite(STDOUT, $in = file_get_contents("php://stdin")); fwrite(STDERR, $in);\''; +} +$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); +$stdin = str_repeat('*', 4097); + +$options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false)); +$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options); + +foreach ($pipes as $pipe) { + stream_set_blocking($pipe, false); +} +$writePipes = array($pipes[0]); +$stdinLen = strlen($stdin); +$stdinOffset = 0; + +unset($pipes[0]); + +while ($pipes || $writePipes) { + $r = $pipes; + $w = $writePipes; + $e = null; + $n = stream_select($r, $w, $e, 60); + + if (false === $n) { + break; + } elseif ($n === 0) { + proc_terminate($process); + + } + if ($w) { + $written = fwrite($writePipes[0], (binary)substr($stdin, $stdinOffset), 8192); + if (false !== $written) { + $stdinOffset += $written; + } + if ($stdinOffset >= $stdinLen) { + fclose($writePipes[0]); + $writePipes = null; + } + } + + foreach ($r as $pipe) { + $type = array_search($pipe, $pipes); + $data = fread($pipe, 8192); + var_dump($data); + if (false === $data || feof($pipe)) { + fclose($pipe); + unset($pipes[$type]); + } + } +} + +?> +===DONE=== +--EXPECTF-- +string(4097) "%s" +string(4097) "%s" +string(0) "" +string(0) "" +===DONE=== + |
