Merge branch 'PHP-7.4' into PHP-8.0

* PHP-7.4:
  Fix #80384: limit read buffer size
This commit is contained in:
Christoph M. Becker 2020-12-23 13:52:24 +01:00
commit 7d9ddd61ec
4 changed files with 33 additions and 2 deletions

2
NEWS
View file

@ -4,6 +4,8 @@ PHP NEWS
- Core: - Core:
. Fixed bug #80523 (bogus parse error on >4GB source code). (Nikita) . Fixed bug #80523 (bogus parse error on >4GB source code). (Nikita)
. Fixed bug #80384 (filter buffers entire read until file closed). (Adam
Seitz, cmb)
- Date: - Date:
. Fixed bug #80376 (last day of the month causes runway cpu usage). (Derick) . Fixed bug #80376 (last day of the month causes runway cpu usage). (Derick)

View file

@ -52,6 +52,6 @@ fclose($f2);
--EXPECT-- --EXPECT--
filter onCreate filter onCreate
filtered 8192 bytes. filtered 8192 bytes.
filtered 128 bytes and closing. filtered 128 bytes and closing. Stream has reached end-of-file.
int(8320) int(8320)
filter onClose filter onClose

View file

@ -540,6 +540,7 @@ PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size)
/* allocate/fill the buffer */ /* allocate/fill the buffer */
if (stream->readfilters.head) { if (stream->readfilters.head) {
size_t to_read_now = MIN(size, stream->chunk_size);
char *chunk_buf; char *chunk_buf;
php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL }; php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL };
php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out, *brig_swap; php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out, *brig_swap;
@ -547,7 +548,7 @@ PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size)
/* allocate a buffer for reading chunks */ /* allocate a buffer for reading chunks */
chunk_buf = emalloc(stream->chunk_size); chunk_buf = emalloc(stream->chunk_size);
while (!stream->eof && (stream->writepos - stream->readpos < (zend_off_t)size)) { while (!stream->eof && (stream->writepos - stream->readpos < (zend_off_t)to_read_now)) {
ssize_t justread = 0; ssize_t justread = 0;
int flags; int flags;
php_stream_bucket *bucket; php_stream_bucket *bucket;

28
tests/basic/bug80384.phpt Normal file
View file

@ -0,0 +1,28 @@
--TEST--
Bug #80384 large reads cause filters to internally buffer large amounts of memory
--FILE--
<?php
/* First, create a file to read */
$tmp_filename = __DIR__ . "/bug80384.tmp";
$fp = fopen($tmp_filename, 'w');
for ($i=0; $i<1024; $i++) {
fwrite($fp, str_repeat('ABCDEFGH', 1024));
}
fclose($fp);
/* Stream the file through a filter */
$fp = fopen($tmp_filename, 'r');
$filter = stream_filter_append($fp, "string.rot13");
$mem_start = memory_get_usage();
fread($fp, 8 * 1024 * 1024);
$mem_final = memory_get_usage();
fclose($fp);
var_dump($mem_final - $mem_start < 32768);
?>
--CLEAN--
<?php
unlink(__DIR__ . "/bug80384.tmp");
?>
--EXPECT--
bool(true)