Skip to content

Commit 1ec83d4

Browse files
committed
Fixed bug #61019 (Out of memory on command stream_get_contents)
1 parent 91a9d24 commit 1ec83d4

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ PHP NEWS
33
?? ??? 2014, PHP 5.4.28
44

55
- Core:
6+
. Fixed bug #61019 (Out of memory on command stream_get_contents). (Mike)
67
. Fixed bug #64330 (stream_socket_server() creates wrong Abstract Namespace
78
UNIX sockets). (Mike)
89

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
--TEST--
2+
Bug #61019 (Out of memory on command stream_get_contents)
3+
--FILE--
4+
<?php
5+
6+
echo "Test\n";
7+
8+
$descriptorspec = array(
9+
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
10+
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
11+
2 => array("pipe", "w") // stderr is a pipe that the child will write to
12+
);
13+
14+
$process=proc_open("echo testtext",$descriptorspec,$pipes);
15+
if(is_resource($process))
16+
{
17+
stream_set_blocking($pipes[0],false);
18+
stream_set_blocking($pipes[1],false);
19+
stream_set_blocking($pipes[2],false);
20+
stream_set_write_buffer($pipes[0],0);
21+
stream_set_read_buffer($pipes[1],0);
22+
stream_set_read_buffer($pipes[2],0);
23+
$stdin_stream="";
24+
$stderr_stream="";
25+
26+
echo "External command executed\n";
27+
do
28+
{
29+
$process_state=proc_get_status($process);
30+
$tmp_stdin=stream_get_contents($pipes[1]);
31+
if($tmp_stdin)
32+
{
33+
$stdin_stream=$stdin_stream.$tmp_stdin;
34+
}
35+
$tmp_stderr=stream_get_contents($pipes[2]);
36+
if($tmp_stderr)
37+
{
38+
$stderr_stream=$stderr_stream.$tmp_stderr;
39+
}
40+
} while($process_state['running']);
41+
42+
echo "External command exit: ".$process_state['exitcode']."\n";
43+
44+
//read outstanding data
45+
$tmp_stdin=stream_get_contents($pipes[1]);
46+
if($tmp_stdin)
47+
{
48+
$stdin_stream=$stdin_stream.$tmp_stdin;
49+
}
50+
$tmp_stderr=stream_get_contents($pipes[2]);
51+
if($tmp_stderr)
52+
{
53+
$stderr_stream=$stderr_stream.$tmp_stderr;
54+
}
55+
56+
fclose ($pipes[0]);
57+
fclose ($pipes[1]);
58+
fclose ($pipes[2]);
59+
60+
proc_close($process);
61+
62+
echo "STDOUT: ".$stdin_stream."\n";
63+
echo "STDERR: ".$stderr_stream."\n";
64+
}
65+
else
66+
{
67+
echo "Can't start external command\n";
68+
}
69+
?>
70+
===DONE===
71+
--EXPECT--
72+
Test
73+
External command executed
74+
External command exit: 0
75+
STDOUT: testtext
76+
77+
STDERR:
78+
===DONE===

main/streams/streams.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,10 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS
736736

737737
if (!stream->readfilters.head && (stream->flags & PHP_STREAM_FLAG_NO_BUFFER || stream->chunk_size == 1)) {
738738
toread = stream->ops->read(stream, buf, size TSRMLS_CC);
739+
if (toread == (size_t) -1) {
740+
/* e.g. underlying read(2) returned -1 */
741+
break;
742+
}
739743
} else {
740744
php_stream_fill_read_buffer(stream, size TSRMLS_CC);
741745

0 commit comments

Comments
 (0)