summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Bonneau <matt@bonneau.net>2017-03-13 00:11:30 -0400
committerBob Weinand <bobwei9@hotmail.com>2017-03-15 00:08:32 +0100
commit7fba8bda4c9e89c522e5d27a38489125e36b9904 (patch)
treef1c6aa718d2d8239c7a667a4f4dd9d523ec065af
parent8be63ce0e2046e67e403f5ccd5aa06ecdd94e25c (diff)
downloadphp-git-7fba8bda4c9e89c522e5d27a38489125e36b9904.tar.gz
Fixed bug #74240 (deflate_add can allocate too much memory)
-rw-r--r--NEWS5
-rw-r--r--ext/zlib/tests/bug74240.phpt30
-rw-r--r--ext/zlib/zlib.c6
3 files changed, 36 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index 17048a4a7d..071fcc87f9 100644
--- a/NEWS
+++ b/NEWS
@@ -23,9 +23,12 @@ PHP NEWS
. Fixed bug #71003 (Expose MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT to PDO
interface). (Thomas Orozco)
-. Streams:
+- Streams:
. Fixed bug #74216 (Correctly fail on invalid IP address ports). (Sara)
+- Zlib:
+ . Fixed bug #74240 (deflate_add can allocate too much memory). (Matt Bonneau)
+
16 Mar 2017 PHP 7.0.17
- Core:
diff --git a/ext/zlib/tests/bug74240.phpt b/ext/zlib/tests/bug74240.phpt
new file mode 100644
index 0000000000..f3d656ae9d
--- /dev/null
+++ b/ext/zlib/tests/bug74240.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #74240 (deflate_add can allocate too much memory)
+--SKIPIF--
+<?php
+if (!extension_loaded("zlib")) {
+ print "skip - ZLIB extension not loaded";
+}
+?>
+--FILE--
+<?php
+
+ini_set('memory_limit', '64M');
+
+$deflator = deflate_init(ZLIB_ENCODING_RAW);
+
+$bytes = str_repeat("*", 65536);
+
+// this crashes after about 500 iterations if PHP is
+// configured for 64M
+for ($i = 0; $i < 1000; $i++) {
+ $output = deflate_add(
+ $deflator,
+ $bytes,
+ ZLIB_SYNC_FLUSH
+ );
+}
+echo "Completed\n";
+?>
+--EXPECT--
+Completed
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 5c558ea6a6..80607b6600 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -1154,10 +1154,8 @@ PHP_FUNCTION(deflate_add)
RETURN_EMPTY_STRING();
}
- out_size = PHP_ZLIB_BUFFER_SIZE_GUESS(ctx->total_in + in_len);
- out_size = (ctx->total_out >= out_size) ? 16 : (out_size - ctx->total_out);
- out_size = (out_size < 16) ? 16 : out_size;
- out_size += 64;
+ out_size = PHP_ZLIB_BUFFER_SIZE_GUESS(in_len);
+ out_size = (out_size < 64) ? 64 : out_size;
out = zend_string_alloc(out_size, 0);
ctx->next_in = (Bytef *) in_buf;