From 252bc44da55484541c73dc40869a87c03098b9ef Mon Sep 17 00:00:00 2001 From: Adam Seitz Date: Sat, 21 Nov 2020 16:56:55 -0500 Subject: [PATCH 1/2] Fix #80384: limit read buffer size In the case of a stream with no filters, php_stream_fill_read_buffer only reads stream->chunk_size into the read buffer. If the stream has filters attached, it could unnecessarily buffer a large amount of data. With this change, php_stream_fill_read_buffer only proceeds until either the requested size or stream->chunk_size is available in the read buffer. --- main/streams/streams.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/streams/streams.c b/main/streams/streams.c index ab413872e0bd4..5f6bf88aa989a 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -542,6 +542,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; @@ -549,7 +550,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; From f65d3ed032484de4a219b49520187875594dfdc7 Mon Sep 17 00:00:00 2001 From: Adam Seitz Date: Tue, 1 Dec 2020 18:40:16 -0500 Subject: [PATCH 2/2] Add test for bug #80384 --- tests/basic/bug80384.phpt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/basic/bug80384.phpt diff --git a/tests/basic/bug80384.phpt b/tests/basic/bug80384.phpt new file mode 100644 index 0000000000000..cf30e8601b161 --- /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-- + +--CLEAN-- + +--EXPECT-- +bool(true)