Skip to content

Commit 7d9ddd6

Browse files
committed
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4: Fix #80384: limit read buffer size
2 parents 2883320 + 70dfbe0 commit 7d9ddd6

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ PHP NEWS
44

55
- Core:
66
. Fixed bug #80523 (bogus parse error on >4GB source code). (Nikita)
7+
. Fixed bug #80384 (filter buffers entire read until file closed). (Adam
8+
Seitz, cmb)
79

810
- Date:
911
. Fixed bug #80376 (last day of the month causes runway cpu usage). (Derick)

ext/standard/tests/streams/bug79984.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,6 @@ fclose($f2);
5252
--EXPECT--
5353
filter onCreate
5454
filtered 8192 bytes.
55-
filtered 128 bytes and closing.
55+
filtered 128 bytes and closing. Stream has reached end-of-file.
5656
int(8320)
5757
filter onClose

main/streams/streams.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -540,14 +540,15 @@ PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size)
540540
/* allocate/fill the buffer */
541541

542542
if (stream->readfilters.head) {
543+
size_t to_read_now = MIN(size, stream->chunk_size);
543544
char *chunk_buf;
544545
php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL };
545546
php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out, *brig_swap;
546547

547548
/* allocate a buffer for reading chunks */
548549
chunk_buf = emalloc(stream->chunk_size);
549550

550-
while (!stream->eof && (stream->writepos - stream->readpos < (zend_off_t)size)) {
551+
while (!stream->eof && (stream->writepos - stream->readpos < (zend_off_t)to_read_now)) {
551552
ssize_t justread = 0;
552553
int flags;
553554
php_stream_bucket *bucket;

tests/basic/bug80384.phpt

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Bug #80384 large reads cause filters to internally buffer large amounts of memory
3+
--FILE--
4+
<?php
5+
/* First, create a file to read */
6+
$tmp_filename = __DIR__ . "/bug80384.tmp";
7+
$fp = fopen($tmp_filename, 'w');
8+
for ($i=0; $i<1024; $i++) {
9+
fwrite($fp, str_repeat('ABCDEFGH', 1024));
10+
}
11+
fclose($fp);
12+
13+
/* Stream the file through a filter */
14+
$fp = fopen($tmp_filename, 'r');
15+
$filter = stream_filter_append($fp, "string.rot13");
16+
17+
$mem_start = memory_get_usage();
18+
fread($fp, 8 * 1024 * 1024);
19+
$mem_final = memory_get_usage();
20+
fclose($fp);
21+
var_dump($mem_final - $mem_start < 32768);
22+
?>
23+
--CLEAN--
24+
<?php
25+
unlink(__DIR__ . "/bug80384.tmp");
26+
?>
27+
--EXPECT--
28+
bool(true)

0 commit comments

Comments
 (0)