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