diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2016-11-26 15:34:27 +0100 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2016-11-26 15:34:27 +0100 |
commit | 003727d851da770c60555a2aecf6d82497b04f42 (patch) | |
tree | d76be1a62051e6e7816893f5aa671e89188fe1bf | |
parent | 8be94d46f836a886d85b9a813b241a7f26649020 (diff) | |
download | php-git-003727d851da770c60555a2aecf6d82497b04f42.tar.gz |
Fix #73612: preg_*() may leak memory
We have to make sure that collectible zvals end up in the GC root
buffer, to avoid memory leaks.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/pcre/php_pcre.c | 10 | ||||
-rw-r--r-- | ext/pcre/tests/bug73612.phpt | 27 |
3 files changed, 35 insertions, 5 deletions
@@ -6,6 +6,9 @@ PHP NEWS . Fixed bug #73585 (Logging of "Internal Zend error - Missing class information" missing class name). (Laruence) +- PCRE: + . Fixed bug #73612 (preg_*() may leak memory). (cmb) + 08 Dec 2016 PHP 7.0.14 - Core: diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 8601b731f5..af1916aa45 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -726,7 +726,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec /* Overwrite the passed-in value for subpatterns with an empty array. */ if (subpats != NULL) { - zval_dtor(subpats); + zval_ptr_dtor(subpats); array_init(subpats); } @@ -1592,7 +1592,7 @@ static PHP_FUNCTION(preg_replace) replace_count = preg_replace_impl(return_value, regex, replace, subject, limit, 0, 0); if (zcount) { - zval_dtor(zcount); + zval_ptr_dtor(zcount); ZVAL_LONG(zcount, replace_count); } } @@ -1627,7 +1627,7 @@ static PHP_FUNCTION(preg_replace_callback) replace_count = preg_replace_impl(return_value, regex, replace, subject, limit, 1, 0); if (zcount) { - zval_dtor(zcount); + zval_ptr_dtor(zcount); ZVAL_LONG(zcount, replace_count); } } @@ -1689,7 +1689,7 @@ static PHP_FUNCTION(preg_replace_callback_array) } ZEND_HASH_FOREACH_END(); if (zcount) { - zval_dtor(zcount); + zval_ptr_dtor(zcount); ZVAL_LONG(zcount, replace_count); } } @@ -1720,7 +1720,7 @@ static PHP_FUNCTION(preg_filter) replace_count = preg_replace_impl(return_value, regex, replace, subject, limit, 0, 1); if (zcount) { - zval_dtor(zcount); + zval_ptr_dtor(zcount); ZVAL_LONG(zcount, replace_count); } } diff --git a/ext/pcre/tests/bug73612.phpt b/ext/pcre/tests/bug73612.phpt new file mode 100644 index 0000000000..707e10bce6 --- /dev/null +++ b/ext/pcre/tests/bug73612.phpt @@ -0,0 +1,27 @@ +--TEST--
+Bug #73612 (preg_*() may leak memory)
+--FILE--
+<?php
+$obj = new stdClass;
+$obj->obj = $obj;
+preg_match('/./', 'x', $obj);
+
+$obj = new stdClass;
+$obj->obj = $obj;
+preg_replace('/./', '', 'x', -1, $obj);
+
+$obj = new stdClass;
+$obj->obj = $obj;
+preg_replace_callback('/./', 'count', 'x', -1, $obj);
+
+$obj = new stdClass;
+$obj->obj = $obj;
+preg_replace_callback_array(['/./' => 'count'], 'x', -1, $obj);
+
+$obj = new stdClass;
+$obj->obj = $obj;
+preg_filter('/./', '', 'x', -1, $obj);
+?>
+===DONE===
+--EXPECT--
+===DONE===
|