com php-src: Fixed bug #61019 (Out of memory on command stream_get_contents): NEWS ext/standard/tests/strea ms/bug61019.phpt main/streams/streams.c
| From: | Michael Wallner | Date: | Wed, 02 Apr 2014 13:36:39 +0000 |
| Subject: | com php-src: Fixed bug #61019 (Out of memory on command stream_get_contents): NEWS ext/standard/tests/strea ms/bug61019.phpt main/streams/streams.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-76684@lists.php.net to get a copy of this message | ||
Commit: 1ec83d44a1601c3560f430e08af9698bf8fb075c
Author: Michael Wallner <mike@php.net> Wed, 2 Apr 2014 15:36:39 +0200
Parents: 91a9d24aa30507e6c7d8937db2de24394f0ce121
Branches: PHP-5.4 PHP-5.5 PHP-5.6 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=1ec83d44a1601c3560f430e08af9698bf8fb075c
Log:
Fixed bug #61019 (Out of memory on command stream_get_contents)
Bugs:
https://bugs.php.net/61019
Changed paths:
M NEWS
A ext/standard/tests/streams/bug61019.phpt
M main/streams/streams.c
Diff:
diff --git a/NEWS b/NEWS
index 51ed4f3..bc329ad 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ PHP NEWS
?? ??? 2014, PHP 5.4.28
- Core:
+ . Fixed bug #61019 (Out of memory on command stream_get_contents). (Mike)
. Fixed bug #64330 (stream_socket_server() creates wrong Abstract Namespace
UNIX sockets). (Mike)
diff --git a/ext/standard/tests/streams/bug61019.phpt b/ext/standard/tests/streams/bug61019.phpt
new file mode 100644
index 0000000..45b207e
--- /dev/null
+++ b/ext/standard/tests/streams/bug61019.phpt
@@ -0,0 +1,78 @@
+--TEST--
+Bug #61019 (Out of memory on command stream_get_contents)
+--FILE--
+<?php
+
+echo "Test\n";
+
+$descriptorspec = array(
+ 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
+ 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
+ 2 => array("pipe", "w") // stderr is a pipe that the child will write to
+);
+
+$process=proc_open("echo testtext",$descriptorspec,$pipes);
+if(is_resource($process))
+{
+ stream_set_blocking($pipes[0],false);
+ stream_set_blocking($pipes[1],false);
+ stream_set_blocking($pipes[2],false);
+ stream_set_write_buffer($pipes[0],0);
+ stream_set_read_buffer($pipes[1],0);
+ stream_set_read_buffer($pipes[2],0);
+ $stdin_stream="";
+ $stderr_stream="";
+
+ echo "External command executed\n";
+ do
+ {
+ $process_state=proc_get_status($process);
+ $tmp_stdin=stream_get_contents($pipes[1]);
+ if($tmp_stdin)
+ {
+ $stdin_stream=$stdin_stream.$tmp_stdin;
+ }
+ $tmp_stderr=stream_get_contents($pipes[2]);
+ if($tmp_stderr)
+ {
+ $stderr_stream=$stderr_stream.$tmp_stderr;
+ }
+ } while($process_state['running']);
+
+ echo "External command exit: ".$process_state['exitcode']."\n";
+
+ //read outstanding data
+ $tmp_stdin=stream_get_contents($pipes[1]);
+ if($tmp_stdin)
+ {
+ $stdin_stream=$stdin_stream.$tmp_stdin;
+ }
+ $tmp_stderr=stream_get_contents($pipes[2]);
+ if($tmp_stderr)
+ {
+ $stderr_stream=$stderr_stream.$tmp_stderr;
+ }
+
+ fclose ($pipes[0]);
+ fclose ($pipes[1]);
+ fclose ($pipes[2]);
+
+ proc_close($process);
+
+ echo "STDOUT: ".$stdin_stream."\n";
+ echo "STDERR: ".$stderr_stream."\n";
+}
+else
+{
+ echo "Can't start external command\n";
+}
+?>
+===DONE===
+--EXPECT--
+Test
+External command executed
+External command exit: 0
+STDOUT: testtext
+
+STDERR:
+===DONE===
diff --git a/main/streams/streams.c b/main/streams/streams.c
index cac50ef..acc67dc 100644
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -736,6 +736,10 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size
TSRMLS
if (!stream->readfilters.head && (stream->flags & PHP_STREAM_FLAG_NO_BUFFER ||
stream->chunk_size == 1)) {
toread = stream->ops->read(stream, buf, size TSRMLS_CC);
+ if (toread == (size_t) -1) {
+ /* e.g. underlying read(2) returned -1 */
+ break;
+ }
} else {
php_stream_fill_read_buffer(stream, size TSRMLS_CC);