From e6f55339ccf923390da1ea354631809acb2e3729 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Jul 2015 18:33:01 +0200 Subject: add new error constant PREG_JIT_STACKLIMIT_ERROR --- ext/pcre/php_pcre.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 8e40f84673..e57bbd9e38 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -50,7 +50,8 @@ enum { PHP_PCRE_BACKTRACK_LIMIT_ERROR, PHP_PCRE_RECURSION_LIMIT_ERROR, PHP_PCRE_BAD_UTF8_ERROR, - PHP_PCRE_BAD_UTF8_OFFSET_ERROR + PHP_PCRE_BAD_UTF8_OFFSET_ERROR, + PHP_PCRE_JIT_STACKLIMIT_ERROR }; @@ -77,6 +78,12 @@ static void pcre_handle_exec_error(int pcre_code) /* {{{ */ case PCRE_ERROR_BADUTF8_OFFSET: preg_code = PHP_PCRE_BAD_UTF8_OFFSET_ERROR; break; + +#ifdef PCRE_STUDY_JIT_COMPILE + case PCRE_ERROR_JIT_STACKLIMIT: + preg_code = PHP_PCRE_JIT_STACKLIMIT_ERROR; + break; +#endif default: preg_code = PHP_PCRE_INTERNAL_ERROR; @@ -169,6 +176,7 @@ static PHP_MINIT_FUNCTION(pcre) REGISTER_LONG_CONSTANT("PREG_RECURSION_LIMIT_ERROR", PHP_PCRE_RECURSION_LIMIT_ERROR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PREG_BAD_UTF8_ERROR", PHP_PCRE_BAD_UTF8_ERROR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PREG_BAD_UTF8_OFFSET_ERROR", PHP_PCRE_BAD_UTF8_OFFSET_ERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PREG_JIT_STACKLIMIT_ERROR", PHP_PCRE_JIT_STACKLIMIT_ERROR, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("PCRE_VERSION", (char *)pcre_version(), CONST_CS | CONST_PERSISTENT); return SUCCESS; -- cgit v1.2.1 From b9f23c2152eb635082e43e62a5c395b16f40054e Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 13 Aug 2015 14:20:04 +0200 Subject: Fix #70232: Incorrect bump-along behavior with \K and empty string match To do global matching (/g), for every empty match we have to do a second match with PCRE_NOTEMPTY turned on. That may fail, however, when the \K escape sequence is involved. For this purpose libpcre 8.0 introduced the PCRE_NOTEMPTY_ATSTART flag, which we will use if available, and otherwise fall back to the old (possibly buggy) behavior. --- ext/pcre/php_pcre.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index f7afc47458..c55828bbcb 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -43,6 +43,11 @@ #define PCRE_CACHE_SIZE 4096 +/* not fully functional workaround for libpcre < 8.0, see bug #70232 */ +#ifndef PCRE_NOTEMPTY_ATSTART +# define PCRE_NOTEMPTY_ATSTART PCRE_NOTEMPTY +#endif + enum { PHP_PCRE_NO_ERROR = 0, PHP_PCRE_INTERNAL_ERROR, @@ -794,7 +799,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec pcre_free((void *) stringlist); } } else if (count == PCRE_ERROR_NOMATCH) { - /* If we previously set PCRE_NOTEMPTY after a null match, + /* If we previously set PCRE_NOTEMPTY_ATSTART after a null match, this is not necessarily the end. We need to advance the start offset, and continue. Fudge the offset values to achieve this, unless we're already at the end of the string. */ @@ -811,10 +816,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec } /* If we have matched an empty string, mimic what Perl's /g options does. - This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try + This turns out to be rather cunning. First we set PCRE_NOTEMPTY_ATSTART and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ - g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0; + g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED : 0; /* Advance to the position right after the last full match */ start_offset = offsets[1]; @@ -1256,7 +1261,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub limit--; } else if (count == PCRE_ERROR_NOMATCH || limit == 0) { - /* If we previously set PCRE_NOTEMPTY after a null match, + /* If we previously set PCRE_NOTEMPTY_ATSTART after a null match, this is not necessarily the end. We need to advance the start offset, and continue. Fudge the offset values to achieve this, unless we're already at the end of the string. */ @@ -1290,10 +1295,10 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub } /* If we have matched an empty string, mimic what Perl's /g options does. - This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try + This turns out to be rather cunning. First we set PCRE_NOTEMPTY_ATSTART and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ - g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0; + g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED : 0; /* Advance to the next piece. */ start_offset = offsets[1]; @@ -1659,7 +1664,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec } } } else if (count == PCRE_ERROR_NOMATCH) { - /* If we previously set PCRE_NOTEMPTY after a null match, + /* If we previously set PCRE_NOTEMPTY_ATSTART after a null match, this is not necessarily the end. We need to advance the start offset, and continue. Fudge the offset values to achieve this, unless we're already at the end of the string. */ @@ -1691,10 +1696,10 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec } /* If we have matched an empty string, mimic what Perl's /g options does. - This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try + This turns out to be rather cunning. First we set PCRE_NOTEMPTY_ATSTART and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ - g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0; + g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED : 0; /* Advance to the position right after the last full match */ start_offset = offsets[1]; -- cgit v1.2.1 From 1553ce2093bb959f926cc43a8bf6c3c36d5b0223 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 25 Aug 2015 22:47:23 +0200 Subject: add some range checks to pcre --- ext/pcre/php_pcre.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 4da75ec4e8..55ca8fa70e 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -613,6 +613,11 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); #endif + if (ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(subject))) { + php_error_docref(NULL, E_WARNING, "Subject is too long"); + RETURN_FALSE; + } + /* Compile regex or get it from cache. */ if ((pce = pcre_get_compiled_regex_cache(regex)) == NULL) { RETURN_FALSE; @@ -1355,6 +1360,11 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub /* FIXME: This might need to be changed to ZSTR_EMPTY_ALLOC(). Check if this zval could be dtor()'ed somehow */ ZVAL_EMPTY_STRING(&empty_replace); + if (ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(subject_str))) { + php_error_docref(NULL, E_WARNING, "Subject is too long"); + return NULL; + } + /* If regex is an array */ if (Z_TYPE_P(regex) == IS_ARRAY) { replace_value = replace; @@ -1699,6 +1709,11 @@ static PHP_FUNCTION(preg_split) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); #endif + if (ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(subject))) { + php_error_docref(NULL, E_WARNING, "Subject is too long"); + RETURN_FALSE; + } + /* Compile regex or get it from cache. */ if ((pce = pcre_get_compiled_regex_cache(regex)) == NULL) { RETURN_FALSE; -- cgit v1.2.1 From 03964892c054d0c736414c10b3edc7a40318b975 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Fri, 28 Aug 2015 22:52:50 -0700 Subject: Fix bug #70345 (Multiple vulnerabilities related to PCRE functions) --- ext/pcre/php_pcre.c | 152 ++++++++++++++++++++++++++-------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index d7a4309b24..071b1a7dcf 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -136,7 +136,7 @@ static PHP_MINFO_FUNCTION(pcre) static PHP_MINIT_FUNCTION(pcre) { REGISTER_INI_ENTRIES(); - + REGISTER_LONG_CONSTANT("PREG_PATTERN_ORDER", PREG_PATTERN_ORDER, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PREG_SET_ORDER", PREG_SET_ORDER, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PREG_OFFSET_CAPTURE", PREG_OFFSET_CAPTURE, CONST_CS | CONST_PERSISTENT); @@ -276,18 +276,18 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le #endif } } - + p = regex; - + /* Parse through the leading whitespace, and display a warning if we get to the end without encountering a delimiter. */ while (isspace((int)*(unsigned char *)p)) p++; if (*p == 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL TSRMLS_CC, E_WARNING, p < regex + regex_len ? "Null byte in regex" : "Empty regular expression"); return NULL; } - + /* Get the delimiter and display a warning if it is alphanumeric or a backslash. */ delimiter = *p++; @@ -340,7 +340,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le } return NULL; } - + /* Make a copy of the actual pattern. */ pattern = estrndup(p, pp-p); @@ -348,7 +348,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le pp++; /* Parse through the options, setting appropriate flags. Display - a warning if we encounter an unknown modifier. */ + a warning if we encounter an unknown modifier. */ while (pp < regex + regex_len) { switch (*pp++) { /* Perl compatible options */ @@ -356,7 +356,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le case 'm': coptions |= PCRE_MULTILINE; break; case 's': coptions |= PCRE_DOTALL; break; case 'x': coptions |= PCRE_EXTENDED; break; - + /* PCRE specific options */ case 'A': coptions |= PCRE_ANCHORED; break; case 'D': coptions |= PCRE_DOLLAR_ENDONLY;break; @@ -369,12 +369,12 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le the PCRE_UCP option. */ #ifdef PCRE_UCP coptions |= PCRE_UCP; -#endif +#endif break; /* Custom preg options */ case 'e': poptions |= PREG_REPLACE_EVAL; break; - + case ' ': case '\n': break; @@ -453,7 +453,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le * at end of request. However PCRE_G(pcre_cache) must be consistent * on the next request as well. So we disable usage of interned strings * as hash keys especually for this table. - * See bug #63180 + * See bug #63180 */ if (IS_INTERNED(regex)) { regex = tmp = estrndup(regex, regex_len); @@ -482,7 +482,7 @@ PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *preg_ if (preg_options) { *preg_options = pce ? pce->preg_options : 0; } - + return pce ? pce->re : NULL; } /* }}} */ @@ -492,7 +492,7 @@ PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *preg_ PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *compile_options TSRMLS_DC) { pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex, strlen(regex) TSRMLS_CC); - + if (extra) { *extra = pce ? pce->extra : NULL; } @@ -502,7 +502,7 @@ PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *pr if (compile_options) { *compile_options = pce ? pce->compile_options : 0; } - + return pce ? pce->re : NULL; } /* }}} */ @@ -519,7 +519,7 @@ static inline void add_offset_pair(zval *result, char *str, int len, int offset, /* Add (match, offset) to the return value */ add_next_index_stringl(match_pair, str, len, 1); add_next_index_long(match_pair, offset); - + if (name) { zval_add_ref(&match_pair); zend_hash_update(Z_ARRVAL_P(result), name, strlen(name)+1, &match_pair, sizeof(zval *), NULL); @@ -544,13 +544,13 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * &subject, &subject_len, &subpats, &flags, &start_offset) == FAILURE) { RETURN_FALSE; } - + /* Compile regex or get it from cache. */ if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) { RETURN_FALSE; } - php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, + php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, global, ZEND_NUM_ARGS() >= 4, flags, start_offset TSRMLS_CC); } /* }}} */ @@ -653,7 +653,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec matched = 0; PCRE_G(error_code) = PHP_PCRE_NO_ERROR; - + do { /* Execute the regular expression. */ count = pcre_exec(pce->re, extra, subject, subject_len, start_offset, @@ -675,7 +675,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec /* If subpatterns array has been passed, fill it in with values. */ if (subpats != NULL) { /* Try to get the list of substrings and display a warning if failed. */ - if (pcre_get_substring_list(subject, offsets, count, &stringlist) < 0) { + if ((offsets[1] - offsets[0] < 0) || pcre_get_substring_list(subject, offsets, count, &stringlist) < 0) { efree(subpat_names); efree(offsets); if (match_sets) efree(match_sets); @@ -710,7 +710,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec ALLOC_ZVAL(result_set); array_init(result_set); INIT_PZVAL(result_set); - + /* Add all the subpatterns to it */ for (i = 0; i < count; i++) { if (offset_capture) { @@ -762,13 +762,13 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec pcre_handle_exec_error(count TSRMLS_CC); break; } - + /* If we have matched an empty string, mimic what Perl's /g options does. This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0; - + /* Advance to the position right after the last full match */ start_offset = offsets[1]; } while (global); @@ -785,7 +785,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec } efree(match_sets); } - + efree(offsets); efree(subpat_names); @@ -835,7 +835,7 @@ static int preg_get_backref(char **str, int *backref) walk++; } else return 0; - + if (*walk && *walk >= '0' && *walk <= '9') { *backref = *backref * 10 + *walk - '0'; walk++; @@ -847,9 +847,9 @@ static int preg_get_backref(char **str, int *backref) else walk++; } - + *str = walk; - return 1; + return 1; } /* }}} */ @@ -859,7 +859,7 @@ static int preg_do_repl_func(zval *function, char *subject, int *offsets, char * { zval *retval_ptr; /* Function return value */ zval **args[1]; /* Argument to pass to function */ - zval *subpats; /* Captured subpatterns */ + zval *subpats; /* Captured subpatterns */ int result_len; /* Return value length */ int i; @@ -910,11 +910,11 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, int backref; /* Current backref */ char *compiled_string_description; smart_str code = {0}; - + eval_str_end = eval_str + eval_str_len; walk = segment = eval_str; walk_last = 0; - + while (walk < eval_str_end) { /* If found a backreference.. */ if ('\\' == *walk || '$' == *walk) { @@ -967,15 +967,15 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, } efree(compiled_string_description); convert_to_string(&retval); - + /* Save the return value and its length */ *result = estrndup(Z_STRVAL(retval), Z_STRLEN(retval)); result_len = Z_STRLEN(retval); - + /* Clean up */ zval_dtor(&retval); smart_str_free(&code); - + return result_len; } /* }}} */ @@ -994,13 +994,13 @@ PHPAPI char *php_pcre_replace(char *regex, int regex_len, return NULL; } - return php_pcre_replace_impl(pce, subject, subject_len, replace_val, + return php_pcre_replace_impl(pce, subject, subject_len, replace_val, is_callable_replace, result_len, limit, replace_count TSRMLS_CC); } /* }}} */ /* {{{ php_pcre_replace_impl() */ -PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *replace_val, +PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC) { pcre_extra *extra = pce->extra;/* Holds results of studying */ @@ -1072,7 +1072,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub } offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0); - + alloc_len = 2 * subject_len + 1; result = safe_emalloc(alloc_len, sizeof(char), 0); @@ -1081,7 +1081,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub *result_len = 0; start_offset = 0; PCRE_G(error_code) = PHP_PCRE_NO_ERROR; - + while (1) { /* Execute the regular expression. */ count = pcre_exec(pce->re, extra, subject, subject_len, start_offset, @@ -1098,7 +1098,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub piece = subject + start_offset; - if (count > 0 && (limit == -1 || limit > 0)) { + if (count > 0 && (offsets[1] - offsets[0] >= 0) && (limit == -1 || limit > 0)) { if (replace_count) { ++*replace_count; } @@ -1106,7 +1106,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub match = subject + offsets[0]; new_len = *result_len + offsets[0] - start_offset; /* part before the match */ - + /* If evaluating, do it and add the return string's length */ if (eval) { eval_result_len = preg_do_eval(replace, replace_len, subject, @@ -1151,7 +1151,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub /* copy replacement and backrefs */ walkbuf = result + *result_len; - + /* If evaluating or using custom function, copy result to the buffer * and clean up. */ if (eval || is_callable_replace) { @@ -1219,13 +1219,13 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub result = NULL; break; } - + /* If we have matched an empty string, mimic what Perl's /g options does. This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0; - + /* Advance to the next piece. */ start_offset = offsets[1]; } @@ -1249,18 +1249,18 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject, *result; int subject_len; - /* Make sure we're dealing with strings. */ + /* Make sure we're dealing with strings. */ convert_to_string_ex(subject); /* FIXME: This might need to be changed to STR_EMPTY_ALLOC(). Check if this zval could be dtor()'ed somehow */ ZVAL_STRINGL(&empty_replace, "", 0, 0); - + /* If regex is an array */ if (Z_TYPE_P(regex) == IS_ARRAY) { /* Duplicate subject string for repeated replacement */ subject_value = estrndup(Z_STRVAL_PP(subject), Z_STRLEN_PP(subject)); subject_len = Z_STRLEN_PP(subject); *result_len = subject_len; - + zend_hash_internal_pointer_reset(Z_ARRVAL_P(regex)); replace_value = replace; @@ -1269,9 +1269,9 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject, /* For each entry in the regex array, get the entry */ while (zend_hash_get_current_data(Z_ARRVAL_P(regex), (void **)®ex_entry) == SUCCESS) { - /* Make sure we're dealing with strings. */ + /* Make sure we're dealing with strings. */ convert_to_string_ex(regex_entry); - + /* If replace is an array and not a callable construct */ if (Z_TYPE_P(replace) == IS_ARRAY && !is_callable_replace) { /* Get current entry */ @@ -1286,7 +1286,7 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject, replace_value = &empty_replace; } } - + /* Do the actual replacement and put the result back into subject_value for further replacements. */ if ((result = php_pcre_replace(Z_STRVAL_PP(regex_entry), @@ -1342,12 +1342,12 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl ulong num_key; char *callback_name; int replace_count=0, old_replace_count; - + /* Get function parameters and do error-checking. */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|lZ", ®ex, &replace, &subject, &limit, &zcount) == FAILURE) { return; } - + if (!is_callable_replace && Z_TYPE_PP(replace) == IS_ARRAY && Z_TYPE_PP(regex) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter mismatch, pattern is a string while replacement is an array"); RETURN_FALSE; @@ -1373,10 +1373,10 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl if (ZEND_NUM_ARGS() > 3) { limit_val = limit; } - + if (Z_TYPE_PP(regex) != IS_ARRAY) convert_to_string_ex(regex); - + /* if subject is an array */ if (Z_TYPE_PP(subject) == IS_ARRAY) { array_init(return_value); @@ -1404,7 +1404,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl efree(result); } } - + zend_hash_move_forward(Z_ARRVAL_PP(subject)); } } else { /* if subject is not an array */ @@ -1421,7 +1421,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl zval_dtor(*zcount); ZVAL_LONG(*zcount, replace_count); } - + } /* }}} */ @@ -1449,7 +1449,7 @@ static PHP_FUNCTION(preg_filter) } /* }}} */ -/* {{{ proto array preg_split(string pattern, string subject [, int limit [, int flags]]) +/* {{{ proto array preg_split(string pattern, string subject [, int limit [, int flags]]) Split string into an array using a perl-style regular expression as a delimiter */ static PHP_FUNCTION(preg_split) { @@ -1461,12 +1461,12 @@ static PHP_FUNCTION(preg_split) long flags = 0; /* Match control flags */ pcre_cache_entry *pce; /* Compiled regular expression */ - /* Get function parameters and do error checking */ + /* Get function parameters and do error checking */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", ®ex, ®ex_len, &subject, &subject_len, &limit_val, &flags) == FAILURE) { RETURN_FALSE; } - + /* Compile regex or get it from cache. */ if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) { RETURN_FALSE; @@ -1501,7 +1501,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec no_empty = flags & PREG_SPLIT_NO_EMPTY; delim_capture = flags & PREG_SPLIT_DELIM_CAPTURE; offset_capture = flags & PREG_SPLIT_OFFSET_CAPTURE; - + if (limit_val == 0) { limit_val = -1; } @@ -1512,7 +1512,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec } extra->match_limit = PCRE_G(backtrack_limit); extra->match_limit_recursion = PCRE_G(recursion_limit); - + /* Initialize return value */ array_init(return_value); @@ -1524,13 +1524,13 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec } size_offsets = (size_offsets + 1) * 3; offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0); - + /* Start at the beginning of the string */ start_offset = 0; next_offset = 0; last_match = subject; PCRE_G(error_code) = PHP_PCRE_NO_ERROR; - + /* Get next piece if no limit or limit not yet reached and something matched*/ while ((limit_val == -1 || limit_val > 1)) { count = pcre_exec(pce->re, extra, subject, @@ -1545,9 +1545,9 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec php_error_docref(NULL TSRMLS_CC,E_NOTICE, "Matched, but too many substrings"); count = size_offsets/3; } - + /* If something matched */ - if (count > 0) { + if (count > 0 && (offsets[1] - offsets[0] >= 0)) { if (!no_empty || &subject[offsets[0]] != last_match) { if (offset_capture) { @@ -1563,7 +1563,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec if (limit_val != -1) limit_val--; } - + last_match = &subject[offsets[1]]; next_offset = offsets[1]; @@ -1620,7 +1620,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec the match again at the same point. If this fails (picked up above) we advance to the next character. */ g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0; - + /* Advance to the position right after the last full match */ start_offset = offsets[1]; } @@ -1639,7 +1639,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec } } - + /* Clean up */ efree(offsets); } @@ -1660,13 +1660,13 @@ static PHP_FUNCTION(preg_quote) delim_char=0, /* Delimiter character to be quoted */ c; /* Current character */ zend_bool quote_delim = 0; /* Whether to quote additional delim char */ - + /* Get the arguments and check for errors */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &in_str, &in_str_len, &delim, &delim_len) == FAILURE) { return; } - + in_str_end = in_str + in_str_len; /* Nothing to do if we got an empty string */ @@ -1678,11 +1678,11 @@ static PHP_FUNCTION(preg_quote) delim_char = delim[0]; quote_delim = 1; } - + /* Allocate enough memory so that even if each character is quoted, we won't run out of room */ out_str = safe_emalloc(4, in_str_len, 1); - + /* Go through the string and quote necessary characters */ for(p = in_str, q = out_str; p != in_str_end; p++) { c = *p; @@ -1726,7 +1726,7 @@ static PHP_FUNCTION(preg_quote) } } *q = '\0'; - + /* Reallocate string and return it */ RETVAL_STRINGL(erealloc(out_str, q - out_str + 1), q - out_str, 0); } @@ -1747,12 +1747,12 @@ static PHP_FUNCTION(preg_grep) &input, &flags) == FAILURE) { return; } - + /* Compile regex or get it from cache. */ if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) { RETURN_FALSE; } - + php_pcre_grep_impl(pce, input, return_value, flags TSRMLS_CC); } /* }}} */ @@ -1770,9 +1770,9 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return zend_bool invert; /* Whether to return non-matching entries */ int rc; - + invert = flags & PREG_GREP_INVERT ? 1 : 0; - + if (extra == NULL) { extra_data.flags = PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra = &extra_data; @@ -1788,7 +1788,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return } size_offsets = (size_offsets + 1) * 3; offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0); - + /* Initialize return array */ array_init(return_value); @@ -1901,7 +1901,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_split, 0, 0, 2) ZEND_ARG_INFO(0, pattern) ZEND_ARG_INFO(0, subject) ZEND_ARG_INFO(0, limit) - ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_quote, 0, 0, 1) -- cgit v1.2.1 From 560e4fa39327e952652b6469d9644fc5fa2c15fa Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 29 Sep 2015 11:17:43 +0300 Subject: Removed or simplified incorrect SEPARATE_*() macros usage. --- ext/pcre/php_pcre.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 3ec6e625a0..66ee238dc4 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1446,12 +1446,10 @@ static int preg_replace_impl(zval *return_value, zval *regex, zval *replace, zva int replace_count = 0, old_replace_count; if (Z_TYPE_P(replace) != IS_ARRAY && (Z_TYPE_P(replace) != IS_OBJECT || !is_callable_replace)) { - SEPARATE_ZVAL(replace); convert_to_string_ex(replace); } if (Z_TYPE_P(regex) != IS_ARRAY) { - SEPARATE_ZVAL(regex); convert_to_string_ex(regex); } -- cgit v1.2.1 From 817513af4ec5e5a45fdd7ecd0a00e728d00c3ff3 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 21 Dec 2015 18:09:59 +0800 Subject: Fixed bug #71178 (preg_replace with arrays creates [0] in replace array if not already set) --- ext/pcre/php_pcre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 66ee238dc4..6769eb7d9a 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1380,7 +1380,7 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub /* Get current entry */ replace_entry = NULL; while (replace_idx < Z_ARRVAL_P(replace)->nNumUsed) { - if (Z_TYPE(Z_ARRVAL_P(replace)->arData[replace_idx].val) != IS_UNUSED) { + if (Z_TYPE(Z_ARRVAL_P(replace)->arData[replace_idx].val) != IS_UNDEF) { replace_entry = &Z_ARRVAL_P(replace)->arData[replace_idx].val; break; } -- cgit v1.2.1 From 49493a2dcfb2cd1758b69b13d9006ead3be0e066 Mon Sep 17 00:00:00 2001 From: Lior Kaplan Date: Fri, 1 Jan 2016 19:19:27 +0200 Subject: Happy new year (Update copyright to 2016) --- ext/pcre/php_pcre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 554693d175..6b258b9a20 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2015 The PHP Group | + | Copyright (c) 1997-2016 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | -- cgit v1.2.1 From 336e39f2b194e1425dc363abd18554f60c80bed1 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 7 Feb 2016 23:19:24 +0800 Subject: Fixed bug #71537 (PCRE segfault from Opcache) --- ext/pcre/php_pcre.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index ee3e36b6ab..93bfc00052 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1350,7 +1350,6 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *subject, int limit, int is_callable_replace, int *replace_count) { zval *regex_entry, - *replace_entry = NULL, *replace_value, empty_replace; zend_string *result; @@ -1372,25 +1371,26 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub /* For each entry in the regex array, get the entry */ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(regex), regex_entry) { + zval replace_str; /* Make sure we're dealing with strings. */ zend_string *regex_str = zval_get_string(regex_entry); + ZVAL_UNDEF(&replace_str); /* If replace is an array and not a callable construct */ if (Z_TYPE_P(replace) == IS_ARRAY && !is_callable_replace) { /* Get current entry */ - replace_entry = NULL; while (replace_idx < Z_ARRVAL_P(replace)->nNumUsed) { if (Z_TYPE(Z_ARRVAL_P(replace)->arData[replace_idx].val) != IS_UNDEF) { - replace_entry = &Z_ARRVAL_P(replace)->arData[replace_idx].val; + ZVAL_COPY(&replace_str, &Z_ARRVAL_P(replace)->arData[replace_idx].val); break; } replace_idx++; } - if (replace_entry != NULL) { + if (!Z_ISUNDEF(replace_str)) { if (!is_callable_replace) { - convert_to_string_ex(replace_entry); + convert_to_string(&replace_str); } - replace_value = replace_entry; + replace_value = &replace_str; replace_idx++; } else { /* We've run out of replacement strings, so use an empty one */ @@ -1413,10 +1413,12 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub } else { zend_string_release(subject_str); zend_string_release(regex_str); + zval_dtor(&replace_str); return NULL; } zend_string_release(regex_str); + zval_dtor(&replace_str); } ZEND_HASH_FOREACH_END(); return subject_str; -- cgit v1.2.1 From 5a6da79fd0bd88997b3679578c7702bc74b3f61a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 9 Mar 2016 22:58:57 +0100 Subject: Fix bug #71659 --- ext/pcre/php_pcre.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 93bfc00052..a522109f3e 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1731,8 +1731,6 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec zend_long limit_val, zend_long flags) { pcre_extra *extra = pce->extra;/* Holds results of studying */ - pcre *re_bump = NULL; /* Regex instance for empty matches */ - pcre_extra *extra_bump = NULL; /* Almost dummy */ pcre_extra extra_data; /* Used locally for exec options */ int *offsets; /* Array of subpattern offsets */ int size_offsets; /* Size of the offsets array */ @@ -1840,29 +1838,11 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec the start offset, and continue. Fudge the offset values to achieve this, unless we're already at the end of the string. */ if (g_notempty != 0 && start_offset < subject_len) { - if (pce->compile_options & PCRE_UTF8) { - if (re_bump == NULL) { - int dummy; - zend_string *regex = zend_string_init("/./us", sizeof("/./us")-1, 0); - re_bump = pcre_get_compiled_regex(regex, &extra_bump, &dummy); - zend_string_release(regex); - if (re_bump == NULL) { - RETURN_FALSE; - } - } - count = pcre_exec(re_bump, extra_bump, subject, - subject_len, start_offset, - exoptions, offsets, size_offsets); - if (count < 1) { - php_error_docref(NULL, E_WARNING, "Unknown error"); - RETURN_FALSE; - } - } else { - offsets[0] = start_offset; - offsets[1] = start_offset + 1; - } - } else + offsets[0] = start_offset; + offsets[1] = start_offset + calculate_unit_length(pce, subject + start_offset); + } else { break; + } } else { pcre_handle_exec_error(count); break; -- cgit v1.2.1 From e23a41225fc4ea099b88e7fc450459173443d98f Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 21 Mar 2016 17:15:44 +0100 Subject: Increase PCRE JIT stack size It is done by implementing the custom stack usage. This makes the JIT with mode on more compatible with the JIT mode off. Until now, the default PCRE JIT stack was used which is 32kb big by default. There are situations where some patterns would fail with JIT while working correctly without JIT. The starting size of the JIT stack is still set to 32kb, while the max is set to the permissive 256kb (and can be increased up to 1mb). As until now no suchlike bugs regarding JIT were reported, it is expected, that the stack usage will stay by 32kb in most cases. Though providing the custom stack, applications will have more room for some sporadic stack increase, thus more compatibility. --- ext/pcre/php_pcre.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index a522109f3e..128089c0bd 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -62,6 +62,11 @@ enum { PHPAPI ZEND_DECLARE_MODULE_GLOBALS(pcre) +#ifdef PCRE_STUDY_JIT_COMPILE +#define PCRE_JIT_STACK_MIN_SIZE (32 * 1024) +#define PCRE_JIT_STACK_MAX_SIZE (256 * 1024) +ZEND_TLS pcre_jit_stack *jit_stack = NULL; +#endif static void pcre_handle_exec_error(int pcre_code) /* {{{ */ { @@ -129,6 +134,16 @@ static PHP_GINIT_FUNCTION(pcre) /* {{{ */ static PHP_GSHUTDOWN_FUNCTION(pcre) /* {{{ */ { zend_hash_destroy(&pcre_globals->pcre_cache); + +#ifdef PCRE_STUDY_JIT_COMPILE + /* Stack may only be destroyed when no cached patterns + possibly associated with it do exist. */ + if (jit_stack) { + pcre_jit_stack_free(jit_stack); + jit_stack = NULL; + } +#endif + } /* }}} */ @@ -197,6 +212,19 @@ static PHP_MSHUTDOWN_FUNCTION(pcre) } /* }}} */ +/* {{{ PHP_RINIT_FUNCTION(pcre) */ +static PHP_RINIT_FUNCTION(pcre) +{ +#ifdef PCRE_STUDY_JIT_COMPILE + if (PCRE_G(jit)) { + jit_stack = pcre_jit_stack_alloc(PCRE_JIT_STACK_MIN_SIZE,PCRE_JIT_STACK_MAX_SIZE); + } +#endif + + return SUCCESS; +} +/* }}} */ + /* {{{ static pcre_clean_cache */ static int pcre_clean_cache(zval *data, void *arg) { @@ -461,6 +489,11 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex) extra->flags |= PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra->match_limit = (unsigned long)PCRE_G(backtrack_limit); extra->match_limit_recursion = (unsigned long)PCRE_G(recursion_limit); +#ifdef PCRE_STUDY_JIT_COMPILE + if (PCRE_G(jit) && jit_stack) { + pcre_assign_jit_stack(extra, NULL, jit_stack); + } +#endif } if (error != NULL) { php_error_docref(NULL, E_WARNING, "Error while studying pattern"); @@ -2199,7 +2232,7 @@ zend_module_entry pcre_module_entry = { pcre_functions, PHP_MINIT(pcre), PHP_MSHUTDOWN(pcre), - NULL, + PHP_RINIT(pcre), NULL, PHP_MINFO(pcre), PHP_PCRE_VERSION, -- cgit v1.2.1 From e988239634fa8c9e01373458d84ef84f1f69a223 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 21 Mar 2016 18:59:39 +0100 Subject: decrease the default PCRE JIT stack to 64K --- ext/pcre/php_pcre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 128089c0bd..24ed6ca5d6 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -64,7 +64,7 @@ PHPAPI ZEND_DECLARE_MODULE_GLOBALS(pcre) #ifdef PCRE_STUDY_JIT_COMPILE #define PCRE_JIT_STACK_MIN_SIZE (32 * 1024) -#define PCRE_JIT_STACK_MAX_SIZE (256 * 1024) +#define PCRE_JIT_STACK_MAX_SIZE (64 * 1024) ZEND_TLS pcre_jit_stack *jit_stack = NULL; #endif -- cgit v1.2.1 From 241ba9dcb195160e323847757413603a3cc72a1f Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 22 Mar 2016 21:41:35 +0100 Subject: if there's no JIT support, no RINIT is really needed --- ext/pcre/php_pcre.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 24ed6ca5d6..f6f86304e5 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -212,18 +212,18 @@ static PHP_MSHUTDOWN_FUNCTION(pcre) } /* }}} */ +#ifdef PCRE_STUDY_JIT_COMPILE /* {{{ PHP_RINIT_FUNCTION(pcre) */ static PHP_RINIT_FUNCTION(pcre) { -#ifdef PCRE_STUDY_JIT_COMPILE if (PCRE_G(jit)) { jit_stack = pcre_jit_stack_alloc(PCRE_JIT_STACK_MIN_SIZE,PCRE_JIT_STACK_MAX_SIZE); } -#endif return SUCCESS; } /* }}} */ +#endif /* {{{ static pcre_clean_cache */ static int pcre_clean_cache(zval *data, void *arg) @@ -2232,7 +2232,11 @@ zend_module_entry pcre_module_entry = { pcre_functions, PHP_MINIT(pcre), PHP_MSHUTDOWN(pcre), +#ifdef PCRE_STUDY_JIT_COMPILE PHP_RINIT(pcre), +#else + NULL +#endif NULL, PHP_MINFO(pcre), PHP_PCRE_VERSION, -- cgit v1.2.1 From 37f7c71f3e23d735cd3b75a0e2e05b6de95d3ad5 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 29 Apr 2016 12:33:54 +0300 Subject: Simplified condition --- ext/pcre/php_pcre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index f6f86304e5..35ba1a06f1 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1030,7 +1030,7 @@ static int preg_get_backref(char **str, int *backref) } if (in_brace) { - if (*walk == 0 || *walk != '}') + if (*walk != '}') return 0; else walk++; -- cgit v1.2.1 From 90f46f2c5bdd3ab0e5dbc3aec1b3294ea1981abe Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Sat, 14 May 2016 08:20:41 +0100 Subject: fix #72143 (preg_replace uses int instead of size_t on zend_string_allocs) --- ext/pcre/php_pcre.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 35ba1a06f1..9225c0f976 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1119,8 +1119,8 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su char **subpat_names; /* Array for named subpatterns */ int num_subpats; /* Number of captured subpatterns */ int size_offsets; /* Size of the offsets array */ - int new_len; /* Length of needed storage */ - int alloc_len; /* Actual allocated length */ + size_t new_len; /* Length of needed storage */ + size_t alloc_len; /* Actual allocated length */ int match_len; /* Length of the current match */ int backref; /* Backreference number */ int start_offset; /* Where the new search starts */ -- cgit v1.2.1