summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--ext/standard/tests/streams/bug79984.phpt2
-rw-r--r--main/streams/streams.c3
-rw-r--r--tests/basic/bug80384.phpt28
4 files changed, 33 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 30d7463c2a..1f04b54197 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ PHP NEWS
- Core:
. 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:
. Fixed bug #80376 (last day of the month causes runway cpu usage). (Derick)
diff --git a/ext/standard/tests/streams/bug79984.phpt b/ext/standard/tests/streams/bug79984.phpt
index 7126458fff..3a7eca091a 100644
--- a/ext/standard/tests/streams/bug79984.phpt
+++ b/ext/standard/tests/streams/bug79984.phpt
@@ -52,6 +52,6 @@ fclose($f2);
--EXPECT--
filter onCreate
filtered 8192 bytes.
-filtered 128 bytes and closing.
+filtered 128 bytes and closing. Stream has reached end-of-file.
int(8320)
filter onClose
diff --git a/main/streams/streams.c b/main/streams/streams.c
index 0524bd28a2..86522afa84 100644
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -540,6 +540,7 @@ PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size)
/* allocate/fill the buffer */
if (stream->readfilters.head) {
+ size_t to_read_now = MIN(size, stream->chunk_size);
char *chunk_buf;
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;
@@ -547,7 +548,7 @@ PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size)
/* allocate a buffer for reading chunks */
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;
int flags;
php_stream_bucket *bucket;
diff --git a/tests/basic/bug80384.phpt b/tests/basic/bug80384.phpt
new file mode 100644
index 0000000000..cf30e8601b
--- /dev/null
+++ b/tests/basic/bug80384.phpt
@@ -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)