]> granicus.if.org Git - php/commitdiff
Fix bug #78326
authorAlbert Casademont <albertcasademont@gmail.com>
Tue, 23 Jul 2019 12:03:06 +0000 (14:03 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 29 Jul 2019 15:33:57 +0000 (17:33 +0200)
Similar to what fread() does, truncate the stream_get_contents()
result if the original buffer was way too large.

NEWS
ext/standard/tests/streams/bug78326.phpt [new file with mode: 0644]
ext/standard/tests/streams/bug78326_1.phpt [new file with mode: 0644]
main/streams/streams.c

diff --git a/NEWS b/NEWS
index d76ee3c55a3f2332a363228e74550b2c3572cc0d..d8181a702826bf8514711f395198c08418295c96 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@ PHP                                                                        NEWS
 - Standard:
   . Fixed bug #69100 (Bus error from stream_copy_to_stream (file -> SSL stream)
     with invalid length). (Nikita)
+  . Fixed bug #78326 (improper memory deallocation on stream_get_contents()
+    with fixed length buffer). (Albert Casademont)
 
 01 Aug 2019, PHP 7.2.21
 
diff --git a/ext/standard/tests/streams/bug78326.phpt b/ext/standard/tests/streams/bug78326.phpt
new file mode 100644 (file)
index 0000000..ca27b05
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+memory allocation on stream_get_contents()
+--INI--
+memory_limit=32M
+--FILE--
+<?php
+$f = tmpfile();
+fwrite($f, '.');
+
+$chunks = array();
+for ($i = 0; $i < 1000; ++$i) {
+    rewind($f);
+    $chunks[] = stream_get_contents($f, 1000000);
+}
+var_dump(count($chunks));
+?>
+--EXPECT--
+int(1000)
diff --git a/ext/standard/tests/streams/bug78326_1.phpt b/ext/standard/tests/streams/bug78326_1.phpt
new file mode 100644 (file)
index 0000000..8e3489d
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+proper string length on stream_get_contents()
+--FILE--
+<?php
+$f = fopen('php://memory', 'rw');
+fwrite($f, str_repeat('X', 1000));
+fseek($f, 0);
+var_dump(strlen(stream_get_contents($f, 1024)));
+--EXPECT--
+int(1000)
index 9daae574337a1ade05ac9776b87c9e7d8f067cc9..399ec29810dccc3b2b7261b6673c40a97daf068f 100644 (file)
@@ -1418,8 +1418,13 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int
                        ptr += ret;
                }
                if (len) {
-                       *ptr = '\0';
                        ZSTR_LEN(result) = len;
+                       ZSTR_VAL(result)[len] = '\0';
+
+                       /* Only truncate if the savings are large enough */
+                       if (len < maxlen / 2) {
+                               result = zend_string_truncate(result, len, persistent);
+                       }
                } else {
                        zend_string_free(result);
                        result = NULL;