diff --git a/NEWS b/NEWS index 4b64511d923..1e43c0e9763 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,7 @@ PHP NEWS - PCRE: . Fixed bug #73483 (Segmentation fault on pcre_replace_callback). (Laruence) + . Fixed bug #73612 (preg_*() may leak memory). (cmb) - Postgres: . Fixed bug #73498 (Incorrect SQL generated for pg_copy_to()). (Craig Duncan) diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index c882a092385..6bcaf17d687 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 00000000000..707e10bce68 --- /dev/null +++ b/ext/pcre/tests/bug73612.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #73612 (preg_*() may leak memory) +--FILE-- +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===