Skip to content

Commit dc7aa22

Browse files
acasademontnikic
authored andcommitted
Fix bug #78326
Similar to what fread() does, truncate the stream_get_contents() result if the original buffer was way too large.
1 parent 38f1288 commit dc7aa22

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ PHP NEWS
2020
- Standard:
2121
. Fixed bug #69100 (Bus error from stream_copy_to_stream (file -> SSL stream)
2222
with invalid length). (Nikita)
23+
. Fixed bug #78326 (improper memory deallocation on stream_get_contents()
24+
with fixed length buffer). (Albert Casademont)
2325

2426
01 Aug 2019, PHP 7.2.21
2527

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
memory allocation on stream_get_contents()
3+
--INI--
4+
memory_limit=32M
5+
--FILE--
6+
<?php
7+
$f = tmpfile();
8+
fwrite($f, '.');
9+
10+
$chunks = array();
11+
for ($i = 0; $i < 1000; ++$i) {
12+
rewind($f);
13+
$chunks[] = stream_get_contents($f, 1000000);
14+
}
15+
var_dump(count($chunks));
16+
?>
17+
--EXPECT--
18+
int(1000)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
proper string length on stream_get_contents()
3+
--FILE--
4+
<?php
5+
$f = fopen('php://memory', 'rw');
6+
fwrite($f, str_repeat('X', 1000));
7+
fseek($f, 0);
8+
var_dump(strlen(stream_get_contents($f, 1024)));
9+
--EXPECT--
10+
int(1000)

main/streams/streams.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,8 +1418,13 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int
14181418
ptr += ret;
14191419
}
14201420
if (len) {
1421-
*ptr = '\0';
14221421
ZSTR_LEN(result) = len;
1422+
ZSTR_VAL(result)[len] = '\0';
1423+
1424+
/* Only truncate if the savings are large enough */
1425+
if (len < maxlen / 2) {
1426+
result = zend_string_truncate(result, len, persistent);
1427+
}
14231428
} else {
14241429
zend_string_free(result);
14251430
result = NULL;

0 commit comments

Comments
 (0)