diff options
Diffstat (limited to 'ext/pcre')
-rw-r--r-- | ext/pcre/php_pcre.c | 3 | ||||
-rw-r--r-- | ext/pcre/tests/bug63055.phpt | 23 |
2 files changed, 25 insertions, 1 deletions
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index b1b9e66e9a..1af8151251 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -547,8 +547,9 @@ 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 garbage = *subpats; array_init(subpats); + zval_dtor(&garbage); } subpats_order = global ? PREG_PATTERN_ORDER : 0; diff --git a/ext/pcre/tests/bug63055.phpt b/ext/pcre/tests/bug63055.phpt new file mode 100644 index 0000000000..16c50b54e5 --- /dev/null +++ b/ext/pcre/tests/bug63055.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #63055 (Segfault in zend_gc with SF2 testsuite) +--FILE-- +<?php +/* the default gc root size is 10,000 */ +for ($i=0; $i<9998; $i++) { + $array = array(); + $array[0] = &$array; + unset($array); +} + +$matches = array("foo" => "bar"); /* this bucket will trigger the segfault */ +$dummy = array("dummy"); /* used to trigger gc_collect_cycles */ +$dummy[1] = &$dummy; + +$matches[1] = &$matches; +$matches[2] = $dummy; + +preg_match_all("/(\d)+/", "foo123456bar", $matches); +echo "okey"; +?> +--EXPECTF-- +okey |