summaryrefslogtreecommitdiff
path: root/ext/pcre/php_pcre.c
diff options
context:
space:
mode:
authorJakub Zelenka <bukka@php.net>2016-06-12 18:56:55 +0100
committerJakub Zelenka <bukka@php.net>2016-06-12 18:56:55 +0100
commitb44cf1a8540d321583a0d83ebca688ebab10d3b0 (patch)
treeb7fbafb4113ea150381a9bba7f98f45027e35b0b /ext/pcre/php_pcre.c
parent6ac8bc4ecb1fdf112eefdd16d2c4f971e7ac232a (diff)
parenta2f4c32eb14221de79009aadaa3da9c3349e3526 (diff)
downloadphp-git-b44cf1a8540d321583a0d83ebca688ebab10d3b0.tar.gz
Merge branch 'PHP-7.0' into openssl_error_store
Diffstat (limited to 'ext/pcre/php_pcre.c')
-rw-r--r--ext/pcre/php_pcre.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 93bfc00052..ed0f3b3ac4 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 (64 * 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)
}
/* }}} */
+#ifdef PCRE_STUDY_JIT_COMPILE
+/* {{{ PHP_RINIT_FUNCTION(pcre) */
+static PHP_RINIT_FUNCTION(pcre)
+{
+ if (PCRE_G(jit)) {
+ jit_stack = pcre_jit_stack_alloc(PCRE_JIT_STACK_MIN_SIZE,PCRE_JIT_STACK_MAX_SIZE);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+#endif
+
/* {{{ 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");
@@ -1086,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 */
@@ -1731,8 +1764,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 +1871,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;
@@ -2219,7 +2232,11 @@ zend_module_entry pcre_module_entry = {
pcre_functions,
PHP_MINIT(pcre),
PHP_MSHUTDOWN(pcre),
- NULL,
+#ifdef PCRE_STUDY_JIT_COMPILE
+ PHP_RINIT(pcre),
+#else
+ NULL
+#endif
NULL,
PHP_MINFO(pcre),
PHP_PCRE_VERSION,