Skip to content

Commit

Permalink
Fix bug #78326
Browse files Browse the repository at this point in the history
Similar to what fread() does, truncate the stream_get_contents()
result if the original buffer was way too large.
  • Loading branch information
acasademont authored and nikic committed Jul 29, 2019
1 parent 38f1288 commit dc7aa22
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ PHP NEWS
- Standard:
. Fixed bug #69100 (Bus error from stream_copy_to_stream (file -> SSL stream)
with invalid length). (Nikita)
. Fixed bug #78326 (improper memory deallocation on stream_get_contents()
with fixed length buffer). (Albert Casademont)

01 Aug 2019, PHP 7.2.21

Expand Down
18 changes: 18 additions & 0 deletions ext/standard/tests/streams/bug78326.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
memory allocation on stream_get_contents()
--INI--
memory_limit=32M
--FILE--
<?php
$f = tmpfile();
fwrite($f, '.');

$chunks = array();
for ($i = 0; $i < 1000; ++$i) {
rewind($f);
$chunks[] = stream_get_contents($f, 1000000);
}
var_dump(count($chunks));
?>
--EXPECT--
int(1000)
10 changes: 10 additions & 0 deletions ext/standard/tests/streams/bug78326_1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--TEST--
proper string length on stream_get_contents()
--FILE--
<?php
$f = fopen('php://memory', 'rw');
fwrite($f, str_repeat('X', 1000));
fseek($f, 0);
var_dump(strlen(stream_get_contents($f, 1024)));
--EXPECT--
int(1000)
7 changes: 6 additions & 1 deletion main/streams/streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -1418,8 +1418,13 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int
ptr += ret;
}
if (len) {
*ptr = '\0';
ZSTR_LEN(result) = len;
ZSTR_VAL(result)[len] = '\0';

/* Only truncate if the savings are large enough */
if (len < maxlen / 2) {
result = zend_string_truncate(result, len, persistent);
}
} else {
zend_string_free(result);
result = NULL;
Expand Down

0 comments on commit dc7aa22

Please sign in to comment.