diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-01-23 14:58:01 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-01-23 14:58:10 +0100 |
commit | 6489e2983159be3b8f4482a2cdf29438d0e1610a (patch) | |
tree | ad074dc45ea116248d546620ace6015895d18bd1 | |
parent | 3f020aef85f13e5d6749314cedd1e0e1c5e64ab0 (diff) | |
parent | 67421a780d670ea2eec8157c39f2682bb3cfb7dd (diff) | |
download | php-git-6489e2983159be3b8f4482a2cdf29438d0e1610a.tar.gz |
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
Fixed bug #78902
Add unit test for bug #78902
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/standard/tests/streams/bug78902.phpt | 28 | ||||
-rw-r--r-- | main/streams/streams.c | 11 |
3 files changed, 40 insertions, 2 deletions
@@ -37,6 +37,9 @@ PHP NEWS . Fixed bug #79115 (ReflectionClass::isCloneable call reflected class __destruct). (Nikita) +- Standard: + . Fixed bug #78902 (Memory leak when using stream_filter_append). (liudaixiao) + 23 Jan 2020, PHP 7.4.2 - Core: diff --git a/ext/standard/tests/streams/bug78902.phpt b/ext/standard/tests/streams/bug78902.phpt new file mode 100644 index 0000000000..1216c89bc2 --- /dev/null +++ b/ext/standard/tests/streams/bug78902.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #78902: Memory leak when using stream_filter_append +--INI-- +memory_limit=512k +--FILE-- +<?php + +/** create temporary file 2mb file */ +$tmp_file_name = tempnam(sys_get_temp_dir(), 'test_'); +$fp = fopen($tmp_file_name, 'w+'); +$size = 1024 * 1024 * 2; // 2mb +$chunk = 1024; +while ($size > 0) { + fputs($fp, str_pad('', min($chunk,$size))); + $size -= $chunk; +} +fclose($fp); + +$fp = fopen($tmp_file_name, 'r'); +stream_filter_append($fp, "string.toupper"); +while (!feof($fp)) { + fread($fp, 1); +} +fclose($fp); +var_dump(true); +?> +--EXPECT-- +bool(true) diff --git a/main/streams/streams.c b/main/streams/streams.c index ce370941a8..f269f06f3e 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -590,8 +590,15 @@ PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size) * stream read buffer */ while (brig_inp->head) { bucket = brig_inp->head; - /* grow buffer to hold this bucket - * TODO: this can fail for persistent streams */ + /* reduce buffer memory consumption if possible, to avoid a realloc */ + if (stream->readbuf && stream->readbuflen - stream->writepos < bucket->buflen) { + if (stream->writepos > stream->readpos) { + memmove(stream->readbuf, stream->readbuf + stream->readpos, stream->writepos - stream->readpos); + } + stream->writepos -= stream->readpos; + stream->readpos = 0; + } + /* grow buffer to hold this bucket */ if (stream->readbuflen - stream->writepos < bucket->buflen) { stream->readbuflen += bucket->buflen; stream->readbuf = perealloc(stream->readbuf, stream->readbuflen, |