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 fb951553be0175712f4b757e05004110d7421e04 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 f6f86304e5..ed0f3b3ac4 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 From 9e7afa75140afd047cb95280a610cff9368a7517 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 16 May 2016 11:24:16 +0800 Subject: Revert "fix #72143 (preg_replace uses int instead of size_t on zend_string_allocs)" ABI break This reverts commit fb951553be0175712f4b757e05004110d7421e04. --- 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 ed0f3b3ac4..f6f86304e5 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 */ - size_t new_len; /* Length of needed storage */ - size_t alloc_len; /* Actual allocated length */ + int new_len; /* Length of needed storage */ + int 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 From 0b3a4c6101abeef297bfb415493e96bbeda3d110 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 16 May 2016 06:21:11 -0700 Subject: Revert "Revert "fix #72143 (preg_replace uses int instead of size_t on zend_string_allocs)"" obviously I read the change is in argument lists by mistake :< This reverts commit 9e7afa75140afd047cb95280a610cff9368a7517. --- 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 f6f86304e5..ed0f3b3ac4 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