diff options
author | Anatol Belski <ab@php.net> | 2018-12-01 10:24:06 +0100 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2018-12-01 10:24:06 +0100 |
commit | ef1269d5c158afaf052e3d79591462e0f5372b1a (patch) | |
tree | 4a7e86e2261e112dde83283bb4ab659644c62fef /ext/pcre/php_pcre.c | |
parent | 471eb0dd95e58a5eae7d10b73d2fcb11031cf568 (diff) | |
download | php-git-ef1269d5c158afaf052e3d79591462e0f5372b1a.tar.gz |
Fixed bug #77193 Infinite loop in preg_replace_callback
Don't return preallocated match data more than once in nested calls.
Diffstat (limited to 'ext/pcre/php_pcre.c')
-rw-r--r-- | ext/pcre/php_pcre.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 5165209b85..ff86458fbf 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -901,17 +901,21 @@ PHPAPI pcre2_code* pcre_get_compiled_regex_ex(zend_string *regex, uint32_t *capt required, perhaps just a minimum sized data would suffice. */ PHPAPI pcre2_match_data *php_pcre_create_match_data(uint32_t capture_count, pcre2_code *re) {/*{{{*/ - int rc = 0; assert(NULL != re); - if (!capture_count) { - /* As we deal with a non cached pattern, no other way to gather this info. */ - rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &capture_count); - } + if (EXPECTED(!mdata_used)) { + int rc = 0; + + if (!capture_count) { + /* As we deal with a non cached pattern, no other way to gather this info. */ + rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &capture_count); + } - if (rc >= 0 && capture_count + 1 <= PHP_PCRE_PREALLOC_MDATA_SIZE) { - return mdata; + if (rc >= 0 && capture_count + 1 <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + mdata_used = 1; + return mdata; + } } return pcre2_match_data_create_from_pattern(re, gctx); @@ -919,8 +923,10 @@ PHPAPI pcre2_match_data *php_pcre_create_match_data(uint32_t capture_count, pcre PHPAPI void php_pcre_free_match_data(pcre2_match_data *match_data) {/*{{{*/ - if (match_data != mdata) { + if (UNEXPECTED(match_data != mdata)) { pcre2_match_data_free(match_data); + } else { + mdata_used = 0; } }/*}}}*/ |