diff --git a/NEWS b/NEWS index f17112179cf..0b46c1ad5c7 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ PHP NEWS - Standard: . Fixed bug #81618 (dns_get_record fails on FreeBSD for missing type). (fsbruva) + . Fixed bug #81659 (stream_get_contents() may unnecessarily overallocate). + (cmb) 18 Nov 2021, PHP 7.4.26 diff --git a/ext/standard/tests/streams/bug81659.phpt b/ext/standard/tests/streams/bug81659.phpt new file mode 100644 index 00000000000..62e0cbad181 --- /dev/null +++ b/ext/standard/tests/streams/bug81659.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #81659 (stream_get_contents() may unnecessarily overallocate) +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(1024) +bool(true) diff --git a/main/streams/streams.c b/main/streams/streams.c index d2ee3371c9e..a320a90b525 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1502,9 +1502,9 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int * result may be inaccurate, as the filter may inflate or deflate the * number of bytes that we can read. In order to avoid an upsize followed * by a downsize of the buffer, overestimate by the step size (which is - * 2K). */ + * 8K). */ if (php_stream_stat(src, &ssbuf) == 0 && ssbuf.sb.st_size > 0) { - max_len = ssbuf.sb.st_size + step; + max_len = MAX(ssbuf.sb.st_size - src->position, 0) + step; } else { max_len = step; }