From: Christoph M. Becker Date: Tue, 23 Jun 2015 14:50:52 +0000 (+0200) Subject: Merge branch 'PHP-5.6' X-Git-Tag: php-7.0.0alpha2~2^2~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec8731c46b40769ceac5242c04197e31477bf3d1;p=php Merge branch 'PHP-5.6' * PHP-5.6: Fixed bug #69864 (Segfault in preg_replace_callback) --- ec8731c46b40769ceac5242c04197e31477bf3d1 diff --cc ext/pcre/php_pcre.c index 11b74b45b3,181b633c39..418859f5d2 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@@ -185,15 -167,16 +185,16 @@@ static PHP_MSHUTDOWN_FUNCTION(pcre /* }}} */ /* {{{ static pcre_clean_cache */ -static int pcre_clean_cache(void *data, void *arg TSRMLS_DC) +static int pcre_clean_cache(zval *data, void *arg) { - pcre_cache_entry *pce = (pcre_cache_entry *) data; ++ pcre_cache_entry *pce = (pcre_cache_entry *) Z_PTR_P(data); int *num_clean = (int *)arg; - if (*num_clean > 0) { + if (*num_clean > 0 && !pce->refcount) { (*num_clean)--; - return 1; + return ZEND_HASH_APPLY_REMOVE; } else { - return 0; + return ZEND_HASH_APPLY_KEEP; } } /* }}} */ @@@ -454,26 -444,11 +455,27 @@@ PHPAPI pcre_cache_entry* pcre_get_compi new_entry.preg_options = poptions; new_entry.compile_options = coptions; #if HAVE_SETLOCALE - new_entry.locale = pestrdup(locale, 1); + new_entry.locale = BG(locale_string) ? + ((GC_FLAGS(BG(locale_string)) & IS_STR_PERSISTENT) ? + zend_string_copy(BG(locale_string)) : + zend_string_init(BG(locale_string)->val, BG(locale_string)->len, 1)) : + NULL; new_entry.tables = tables; #endif + new_entry.refcount = 0; + rc = pcre_fullinfo(re, extra, PCRE_INFO_CAPTURECOUNT, &new_entry.capture_count); + if (rc < 0) { + php_error_docref(NULL, E_WARNING, "Internal pcre_fullinfo() error %d", rc); + return NULL; + } + + rc = pcre_fullinfo(re, extra, PCRE_INFO_NAMECOUNT, &new_entry.name_count); + if (rc < 0) { + php_error_docref(NULL, E_WARNING, "Internal pcre_fullinfo() error %d", rc); + return NULL; + } + /* * Interned strings are not duplicated when stored in HashTable, * but all the interned strings created during HTTP request are removed @@@ -584,8 -552,10 +586,10 @@@ static void php_do_pcre_match(INTERNAL_ RETURN_FALSE; } + pce->refcount++; - php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, - global, ZEND_NUM_ARGS() >= 4, flags, start_offset TSRMLS_CC); + php_pcre_match_impl(pce, subject->val, (int)subject->len, return_value, subpats, + global, ZEND_NUM_ARGS() >= 4, flags, start_offset); + pce->refcount--; } /* }}} */ @@@ -1010,21 -1015,24 +1014,25 @@@ static zend_string *preg_do_repl_func(z /* {{{ php_pcre_replace */ -PHPAPI char *php_pcre_replace(char *regex, int regex_len, +PHPAPI zend_string *php_pcre_replace(zend_string *regex, + zend_string *subject_str, char *subject, int subject_len, zval *replace_val, int is_callable_replace, - int *result_len, int limit, int *replace_count TSRMLS_DC) + int limit, int *replace_count) { pcre_cache_entry *pce; /* Compiled regular expression */ - char *result; /* Function result */ ++ zend_string *result; /* Function result */ /* Compile regex or get it from cache. */ - if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) { + if ((pce = pcre_get_compiled_regex_cache(regex)) == NULL) { return NULL; } - - return php_pcre_replace_impl(pce, subject_str, subject, subject_len, replace_val, + pce->refcount++; - result = php_pcre_replace_impl(pce, subject, subject_len, replace_val, - is_callable_replace, result_len, limit, replace_count TSRMLS_CC); ++ result = php_pcre_replace_impl(pce, subject_str, subject, subject_len, replace_val, + is_callable_replace, limit, replace_count); + pce->refcount--; + + return result; } /* }}} */ @@@ -1660,7 -1519,9 +1668,9 @@@ static PHP_FUNCTION(preg_split RETURN_FALSE; } + pce->refcount++; - php_pcre_split_impl(pce, subject, subject_len, return_value, limit_val, flags TSRMLS_CC); + php_pcre_split_impl(pce, subject->val, (int)subject->len, return_value, (int)limit_val, flags); + pce->refcount--; } /* }}} */ @@@ -1967,7 -1805,9 +1977,9 @@@ static PHP_FUNCTION(preg_grep RETURN_FALSE; } + pce->refcount++; - php_pcre_grep_impl(pce, input, return_value, flags TSRMLS_CC); + php_pcre_grep_impl(pce, input, return_value, flags); + pce->refcount--; } /* }}} */