From f4cfaf36e23ca47da3e352e1c60909104c059647 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Feb 2014 10:04:30 +0400 Subject: Use better data structures (incomplete) --- ext/pcre/php_pcre.c | 258 +++++++++++++++++++++++++--------------------------- 1 file changed, 122 insertions(+), 136 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 84ad12311d..a8976eeede 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -86,9 +86,9 @@ static void pcre_handle_exec_error(int pcre_code TSRMLS_DC) /* {{{ */ } /* }}} */ -static void php_free_pcre_cache(void *data) /* {{{ */ +static void php_free_pcre_cache(zval *data) /* {{{ */ { - pcre_cache_entry *pce = (pcre_cache_entry *) data; + pcre_cache_entry *pce = (pcre_cache_entry *) Z_PTR_P(data); if (!pce) return; pefree(pce->re, 1); if (pce->extra) pefree(pce->extra, 1); @@ -167,7 +167,7 @@ static PHP_MSHUTDOWN_FUNCTION(pcre) /* }}} */ /* {{{ static pcre_clean_cache */ -static int pcre_clean_cache(void *data, void *arg TSRMLS_DC) +static int pcre_clean_cache(zval *data, void *arg TSRMLS_DC) { int *num_clean = (int *)arg; @@ -226,7 +226,7 @@ static char **make_subpats_table(int num_subpats, pcre_cache_entry *pce TSRMLS_D /* {{{ pcre_get_compiled_regex_cache */ -PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_len TSRMLS_DC) +PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex TSRMLS_DC) { pcre *re = NULL; pcre_extra *extra; @@ -248,7 +248,6 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le #endif pcre_cache_entry *pce; pcre_cache_entry new_entry; - char *tmp = NULL; #if HAVE_SETLOCALE # if defined(PHP_WIN32) && defined(ZTS) @@ -259,7 +258,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le /* Try to lookup the cached regex entry, and if successful, just pass back the compiled pattern, otherwise go on and compile it. */ - if (zend_hash_find(&PCRE_G(pcre_cache), regex, regex_len+1, (void **)&pce) == SUCCESS) { + pce = zend_hash_find_ptr(&PCRE_G(pcre_cache), regex); + if (pce) { /* * We use a quick pcre_fullinfo() check to see whether cache is corrupted, and if it * is, we flush it and compile the pattern from scratch. @@ -277,14 +277,14 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le } } - p = regex; + p = regex->val; /* 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, - p < regex + regex_len ? "Null byte in regex" : "Empty regular expression"); + p < regex->val + regex->len ? "Null byte in regex" : "Empty regular expression"); return NULL; } @@ -331,7 +331,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le } if (*pp == 0) { - if (pp < regex + regex_len) { + if (pp < regex->val + regex->len) { php_error_docref(NULL TSRMLS_CC,E_WARNING, "Null byte in regex"); } else if (start_delimiter == end_delimiter) { php_error_docref(NULL TSRMLS_CC,E_WARNING, "No ending delimiter '%c' found", delimiter); @@ -349,7 +349,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le /* Parse through the options, setting appropriate flags. Display a warning if we encounter an unknown modifier. */ - while (pp < regex + regex_len) { + while (pp < regex->val + regex->len) { switch (*pp++) { /* Perl compatible options */ case 'i': coptions |= PCRE_CASELESS; break; @@ -455,16 +455,12 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le * as hash keys especually for this table. * See bug #63180 */ - if (IS_INTERNED(regex)) { - regex = tmp = estrndup(regex, regex_len); - } + STR_ADDREF(regex); - zend_hash_update(&PCRE_G(pcre_cache), regex, regex_len+1, (void *)&new_entry, - sizeof(pcre_cache_entry), (void**)&pce); + pce = zend_hash_update_mem(&PCRE_G(pcre_cache), regex, (void *)&new_entry, + sizeof(pcre_cache_entry)); - if (tmp) { - efree(tmp); - } + STR_RELEASE(regex); return pce; } @@ -472,9 +468,9 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le /* {{{ pcre_get_compiled_regex */ -PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *preg_options TSRMLS_DC) +PHPAPI pcre* pcre_get_compiled_regex(zend_string *regex, pcre_extra **extra, int *preg_options TSRMLS_DC) { - pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex, strlen(regex) TSRMLS_CC); + pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC); if (extra) { *extra = pce ? pce->extra : NULL; @@ -489,9 +485,9 @@ PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *preg_ /* {{{ pcre_get_compiled_regex_ex */ -PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *compile_options TSRMLS_DC) +PHPAPI pcre* pcre_get_compiled_regex_ex(zend_string *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); + pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC); if (extra) { *extra = pce ? pce->extra : NULL; @@ -510,43 +506,40 @@ PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *pr /* {{{ add_offset_pair */ static inline void add_offset_pair(zval *result, char *str, int len, int offset, char *name) { - zval *match_pair; + zval match_pair; - ALLOC_ZVAL(match_pair); - array_init(match_pair); - INIT_PZVAL(match_pair); + array_init(&match_pair); /* Add (match, offset) to the return value */ - add_next_index_stringl(match_pair, str, len, 1); - add_next_index_long(match_pair, offset); + 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); + zend_hash_str_update(Z_ARRVAL_P(result), name, strlen(name), &match_pair); } - zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair); } /* }}} */ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ */ { /* parameters */ - char *regex; /* Regular expression */ + zend_string *regex; /* Regular expression */ char *subject; /* String to match against */ - int regex_len; int subject_len; pcre_cache_entry *pce; /* Compiled regular expression */ zval *subpats = NULL; /* Array for subpatterns */ long flags = 0; /* Match control flags */ long start_offset = 0; /* Where the new search starts */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|zll", ®ex, ®ex_len, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ss|zll", ®ex, &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) { + if ((pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC)) == NULL) { RETURN_FALSE; } @@ -559,9 +552,9 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value, zval *subpats, int global, int use_flags, long flags, long start_offset TSRMLS_DC) { - zval *result_set, /* Holds a set of subpatterns after + zval result_set, /* Holds a set of subpatterns after a global match */ - **match_sets = NULL; /* An array of sets of matches for each + *match_sets = NULL; /* An array of sets of matches for each subpattern after a global match */ pcre_extra *extra = pce->extra;/* Holds results of studying */ pcre_extra extra_data; /* Used locally for exec options */ @@ -643,11 +636,9 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec /* Allocate match sets array and initialize the values. */ if (global && subpats && subpats_order == PREG_PATTERN_ORDER) { - match_sets = (zval **)safe_emalloc(num_subpats, sizeof(zval *), 0); + match_sets = (zval *)safe_emalloc(num_subpats, sizeof(zval), 0); for (i=0; i old_replace_count) { /* Add to return array */ - switch(zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key, &string_key_len, &num_key, 0, NULL)) + switch(zend_hash_get_current_key_ex(Z_ARRVAL_P(subject), &string_key, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: - add_assoc_stringl_ex(return_value, string_key, string_key_len, result, result_len, 0); +//??? + add_assoc_stringl_ex(return_value, string_key->val, string_key->len, result, result_len, 0); break; case HASH_KEY_IS_LONG: @@ -1410,21 +1395,22 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl } } - zend_hash_move_forward(Z_ARRVAL_PP(subject)); + zend_hash_move_forward(Z_ARRVAL_P(subject)); } } else { /* if subject is not an array */ old_replace_count = replace_count; - if ((result = php_replace_in_subject(*regex, *replace, subject, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { + if ((result = php_replace_in_subject(regex, replace, subject, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { - RETVAL_STRINGL(result, result_len, 0); +//??? RETVAL_STRINGL(result, result_len, 0); + RETVAL_STRINGL(result, result_len); } else { efree(result); } } } if (ZEND_NUM_ARGS() > 4) { - zval_dtor(*zcount); - ZVAL_LONG(*zcount, replace_count); + zval_dtor(zcount); + ZVAL_LONG(zcount, replace_count); } } @@ -1458,22 +1444,21 @@ static PHP_FUNCTION(preg_filter) Split string into an array using a perl-style regular expression as a delimiter */ static PHP_FUNCTION(preg_split) { - char *regex; /* Regular expression */ + zend_string *regex; /* Regular expression */ char *subject; /* String to match against */ - int regex_len; int subject_len; long limit_val = -1;/* Integer value of limit */ long flags = 0; /* Match control flags */ pcre_cache_entry *pce; /* Compiled regular expression */ /* Get function parameters and do error checking */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", ®ex, ®ex_len, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ss|ll", ®ex, &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) { + if ((pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC)) == NULL) { RETURN_FALSE; } @@ -1597,8 +1582,10 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec if (pce->compile_options & PCRE_UTF8) { if (re_bump == NULL) { int dummy; - - if ((re_bump = pcre_get_compiled_regex("/./us", &extra_bump, &dummy TSRMLS_CC)) == NULL) { + zend_string *regex = STR_INIT("/./us", sizeof("/./us")-1, 0); + re_bump = pcre_get_compiled_regex(regex, &extra_bump, &dummy TSRMLS_CC); + STR_RELEASE(regex); + if (re_bump == NULL) { RETURN_FALSE; } } @@ -1733,7 +1720,8 @@ 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); +//??? RETVAL_STRINGL(erealloc(out_str, q - out_str + 1), q - out_str, 0); + RETVAL_STRINGL(erealloc(out_str, q - out_str + 1), q - out_str); } /* }}} */ @@ -1741,20 +1729,19 @@ static PHP_FUNCTION(preg_quote) Searches array and returns entries which match regex */ static PHP_FUNCTION(preg_grep) { - char *regex; /* Regular expression */ - int regex_len; + zend_string *regex; /* Regular expression */ zval *input; /* Input array */ long flags = 0; /* Match control flags */ pcre_cache_entry *pce; /* Compiled regular expression */ /* Get arguments and do error checking */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|l", ®ex, ®ex_len, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Sa|l", ®ex, &input, &flags) == FAILURE) { return; } /* Compile regex or get it from cache. */ - if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) { + if ((pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC)) == NULL) { RETURN_FALSE; } @@ -1764,14 +1751,13 @@ static PHP_FUNCTION(preg_grep) PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return_value, long flags TSRMLS_DC) /* {{{ */ { - zval **entry; /* An entry in the input array */ + zval *entry; /* An entry in the input array */ pcre_extra *extra = pce->extra;/* Holds results of studying */ pcre_extra extra_data; /* Used locally for exec options */ int *offsets; /* Array of subpattern offsets */ int size_offsets; /* Size of the offsets array */ int count = 0; /* Count of matched subpatterns */ - char *string_key; - uint string_key_len; + zend_string *string_key; ulong num_key; zend_bool invert; /* Whether to return non-matching entries */ @@ -1802,10 +1788,12 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return /* Go through the input array */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); - while (zend_hash_get_current_data(Z_ARRVAL_P(input), (void **)&entry) == SUCCESS) { - zval subject = **entry; + while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) { + zval subject; + + ZVAL_COPY_VALUE(&subject, entry); - if (Z_TYPE_PP(entry) != IS_STRING) { + if (Z_TYPE_P(entry) != IS_STRING) { zval_copy_ctor(&subject); convert_to_string(&subject); } @@ -1827,24 +1815,22 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return /* If the entry fits our requirements */ if ((count > 0 && !invert) || (count == PCRE_ERROR_NOMATCH && invert)) { - Z_ADDREF_PP(entry); + Z_ADDREF_P(entry); /* Add to return array */ - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, NULL)) + switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, - string_key_len, entry, sizeof(zval *), NULL); + zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); break; case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry, - sizeof(zval *), NULL); + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); break; } } - if (Z_TYPE_PP(entry) != IS_STRING) { + if (Z_TYPE_P(entry) != IS_STRING) { zval_dtor(&subject); } -- cgit v1.2.1 From 43b03c74b322d6ceb003a14a7561fdffc4e13072 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 18 Feb 2014 17:42:46 +0800 Subject: Refacting smart_str --- ext/pcre/php_pcre.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index a8976eeede..473a189ce6 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -906,7 +906,7 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, if ('\\' == *walk || '$' == *walk) { smart_str_appendl(&code, segment, walk - segment); if (walk_last == '\\') { - code.c[code.len-1] = *walk++; + code.s->val[code.s->len-1] = *walk++; segment = walk; walk_last = 0; continue; @@ -946,9 +946,9 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, compiled_string_description = zend_make_compiled_string_description("regexp code" TSRMLS_CC); /* Run the code */ - if (zend_eval_stringl(code.c, code.len, &retval, compiled_string_description TSRMLS_CC) == FAILURE) { + if (zend_eval_stringl(code.s->val, code.s->len, &retval, compiled_string_description TSRMLS_CC) == FAILURE) { efree(compiled_string_description); - php_error_docref(NULL TSRMLS_CC,E_ERROR, "Failed evaluating code: %s%s", PHP_EOL, code.c); + php_error_docref(NULL TSRMLS_CC,E_ERROR, "Failed evaluating code: %s%s", PHP_EOL, code.s->val); /* zend_error() does not return in this case */ } efree(compiled_string_description); -- cgit v1.2.1 From 189a39a187c86b95551c342c5085b63ed34a4d3b Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 19 Feb 2014 18:49:00 +0800 Subject: Fixed segfault --- ext/pcre/php_pcre.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 473a189ce6..7a74082b46 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -455,12 +455,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex TSRMLS * as hash keys especually for this table. * See bug #63180 */ - STR_ADDREF(regex); - - pce = zend_hash_update_mem(&PCRE_G(pcre_cache), regex, (void *)&new_entry, - sizeof(pcre_cache_entry)); - - STR_RELEASE(regex); + pce = zend_hash_str_update_mem(&PCRE_G(pcre_cache), regex->val, regex->len, &new_entry, sizeof(pcre_cache_entry)); return pce; } -- cgit v1.2.1 From 077b02326a22d14f4970ffc3770e2a85f0728fb0 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 24 Feb 2014 12:07:09 +0800 Subject: Refactor php_addslashes using zend_string --- ext/pcre/php_pcre.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 7a74082b46..d3bdf87bca 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -881,14 +881,13 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, zval retval; /* Return value from evaluation */ char *eval_str_end, /* End of eval string */ *match, /* Current match for a backref */ - *esc_match, /* Quote-escaped match */ *walk, /* Used to walk the code string */ *segment, /* Start of segment to append while walking */ walk_last; /* Last walked character */ int match_len; /* Length of the match */ - int esc_match_len; /* Length of the quote-escaped match */ int result_len; /* Length of the result of the evaluation */ int backref; /* Current backref */ + zend_string *esc_match; /* Quote-escaped match */ char *compiled_string_description; smart_str code = {0}; @@ -914,22 +913,19 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, match = subject + offsets[backref<<1]; match_len = offsets[(backref<<1)+1] - offsets[backref<<1]; if (match_len) { - esc_match = php_addslashes(match, match_len, &esc_match_len, 0 TSRMLS_CC); + esc_match = php_addslashes(match, match_len, 0 TSRMLS_CC); } else { - esc_match = match; - esc_match_len = 0; + esc_match = STR_INIT(match, match_len, 0); } } else { - esc_match = ""; - esc_match_len = 0; + esc_match = STR_EMPTY_ALLOC(); } - smart_str_appendl(&code, esc_match, esc_match_len); + smart_str_appendl(&code, esc_match->val, esc_match->len); segment = walk; /* Clean up and reassign */ - if (esc_match_len) - efree(esc_match); + STR_RELEASE(esc_match); continue; } } -- cgit v1.2.1 From 639e4e1afac8c79d28e1a4c3df48fc060b35b68e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 25 Feb 2014 16:03:34 +0400 Subject: Changes zend_is_callable() to use zend_string* instead of char* --- ext/pcre/php_pcre.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index d3bdf87bca..c27f3f7eb1 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1320,7 +1320,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl long limit = -1; zend_string *string_key; ulong num_key; - char *callback_name; + zend_string *callback_name; int replace_count=0, old_replace_count; /* Get function parameters and do error-checking. */ @@ -1339,12 +1339,12 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl } if (is_callable_replace) { if (!zend_is_callable(replace, 0, &callback_name TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires argument 2, '%s', to be a valid callback", callback_name); - efree(callback_name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires argument 2, '%s', to be a valid callback", callback_name->val); + STR_RELEASE(callback_name); ZVAL_DUP(return_value, subject); return; } - efree(callback_name); + STR_RELEASE(callback_name); } SEPARATE_ZVAL(regex); -- cgit v1.2.1 From 045c5fddfa79048bd823ff85b5a35dc6f30b1598 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 28 Feb 2014 13:37:55 +0400 Subject: Fixed memory leaks --- ext/pcre/php_pcre.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index c27f3f7eb1..0a62f6f0b2 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -96,6 +96,7 @@ static void php_free_pcre_cache(zval *data) /* {{{ */ if ((void*)pce->tables) pefree((void*)pce->tables, 1); pefree(pce->locale, 1); #endif + pefree(pce, 1); } /* }}} */ @@ -1392,8 +1393,10 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { +//??? TODO: reimpplement to avoid double reallocation //??? RETVAL_STRINGL(result, result_len, 0); RETVAL_STRINGL(result, result_len); + efree(result); } else { efree(result); } -- cgit v1.2.1 From 10c7f2ddbc98dec21e3060fc4c9319465438c9a9 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 6 Mar 2014 23:39:34 +0800 Subject: Fixed IS_REFERENCE handling in preg_match --- ext/pcre/php_pcre.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 0a62f6f0b2..83844b1455 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -539,6 +539,9 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * RETURN_FALSE; } + if (subpats) { + subpats = Z_REFVAL_P(subpats); + } php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, global, ZEND_NUM_ARGS() >= 4, flags, start_offset TSRMLS_CC); } -- cgit v1.2.1 From fff3c54f9e2b5ca17e8725e29454504ba55accc9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 6 Mar 2014 22:07:28 +0400 Subject: Added check --- 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 83844b1455..ce7b04cdf8 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -539,7 +539,7 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * RETURN_FALSE; } - if (subpats) { + if (subpats && Z_TYPE_P(subpats) == IS_REFERENCE) { subpats = Z_REFVAL_P(subpats); } php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, -- cgit v1.2.1 From d599d0cecde196d2063d6b6b56d4ffebbaeab238 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 7 Mar 2014 17:14:16 +0400 Subject: Temporary fix memory leaks --- ext/pcre/php_pcre.c | 3 ++- 1 file changed, 2 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 ce7b04cdf8..e15076072e 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1718,7 +1718,8 @@ static PHP_FUNCTION(preg_quote) /* Reallocate string and return it */ //??? RETVAL_STRINGL(erealloc(out_str, q - out_str + 1), q - out_str, 0); - RETVAL_STRINGL(erealloc(out_str, q - out_str + 1), q - out_str); + RETVAL_STRINGL(out_str, q - out_str); + efree(out_str); } /* }}} */ -- cgit v1.2.1 From b671c3a28a6b72e2beb283cfc759c806d8d0bc01 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 7 Mar 2014 17:17:35 +0400 Subject: Fixed refcounting --- 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 e15076072e..8a5b069ee8 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1813,7 +1813,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return /* If the entry fits our requirements */ if ((count > 0 && !invert) || (count == PCRE_ERROR_NOMATCH && invert)) { - Z_ADDREF_P(entry); + if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry); /* Add to return array */ switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, NULL)) -- cgit v1.2.1 From 6ad3abcd3e77362395bb886a4531059f459bf89d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 7 Mar 2014 17:21:29 +0400 Subject: Temporary fix memory leaks --- ext/pcre/php_pcre.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 8a5b069ee8..1ae46de022 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1379,10 +1379,12 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl case HASH_KEY_IS_STRING: //??? add_assoc_stringl_ex(return_value, string_key->val, string_key->len, result, result_len, 0); + efree(result); break; case HASH_KEY_IS_LONG: add_index_stringl(return_value, num_key, result, result_len, 0); + efree(result); break; } } else { -- cgit v1.2.1 From ef1e006bd67065641726f6ee2a9bd72196eb3125 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 16 Mar 2014 08:44:07 +0800 Subject: Refactor php_pcre_replace to return zend_string --- ext/pcre/php_pcre.c | 124 ++++++++++++++++++++++++---------------------------- 1 file changed, 56 insertions(+), 68 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 1ae46de022..3c60a6a3e4 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -963,10 +963,10 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, /* {{{ php_pcre_replace */ -PHPAPI char *php_pcre_replace(zend_string *regex, +PHPAPI zend_string *php_pcre_replace(zend_string *regex, char *subject, int subject_len, zval *replace_val, int is_callable_replace, - int *result_len, int limit, int *replace_count TSRMLS_DC) + int limit, int *replace_count TSRMLS_DC) { pcre_cache_entry *pce; /* Compiled regular expression */ @@ -976,13 +976,13 @@ PHPAPI char *php_pcre_replace(zend_string *regex, } return php_pcre_replace_impl(pce, subject, subject_len, replace_val, - is_callable_replace, result_len, limit, replace_count TSRMLS_CC); + is_callable_replace, 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, - int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC) +PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *replace_val, + int is_callable_replace, int limit, int *replace_count TSRMLS_DC) { pcre_extra *extra = pce->extra;/* Holds results of studying */ pcre_extra extra_data; /* Used locally for exec options */ @@ -1002,9 +1002,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub int start_offset; /* Where the new search starts */ int g_notempty=0; /* If the match should not be empty */ int replace_len=0; /* Length of replacement string */ - char *result, /* Result of replacement */ - *replace=NULL, /* Replacement string */ - *new_buf, /* Temporary buffer for re-allocation */ + char *replace=NULL, /* Replacement string */ *walkbuf, /* Location of current replacement in the result */ *walk, /* Used to walk the replacement string */ *match, /* The current match */ @@ -1012,7 +1010,9 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub *replace_end=NULL, /* End of replacement string */ *eval_result, /* Result of eval or custom function */ walk_last; /* Last walked character */ - int rc; + int rc, + result_len; /* Length of result */ + zend_string *result; /* Result of replacement */ if (extra == NULL) { extra_data.flags = PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION; @@ -1058,13 +1058,13 @@ 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); + alloc_len = 2 * subject_len; + result = STR_ALLOC(alloc_len * sizeof(char), 0); /* Initialize */ match = NULL; - *result_len = 0; start_offset = 0; + result_len = 0; PCRE_G(error_code) = PHP_PCRE_NO_ERROR; while (1) { @@ -1090,7 +1090,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub /* Set the match location in subject */ match = subject + offsets[0]; - new_len = *result_len + offsets[0] - start_offset; /* part before the match */ + 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) { @@ -1123,25 +1123,22 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub } } - if (new_len + 1 > alloc_len) { - alloc_len = 1 + alloc_len + 2 * new_len; - new_buf = emalloc(alloc_len); - memcpy(new_buf, result, *result_len); - efree(result); - result = new_buf; + if (new_len > alloc_len) { + alloc_len = alloc_len + 2 * new_len; + result = STR_REALLOC(result, alloc_len, 0); } /* copy the part of the string before the match */ - memcpy(&result[*result_len], piece, match-piece); - *result_len += match-piece; + memcpy(&result->val[result_len], piece, match-piece); + result_len += match-piece; /* copy replacement and backrefs */ - walkbuf = result + *result_len; + walkbuf = result->val + result_len; /* If evaluating or using custom function, copy result to the buffer * and clean up. */ if (eval || is_callable_replace) { memcpy(walkbuf, eval_result, eval_result_len); - *result_len += eval_result_len; + result_len += eval_result_len; if (eval_result) efree(eval_result); } else { /* do regular backreference copying */ walk = replace; @@ -1167,7 +1164,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub } *walkbuf = '\0'; /* increment the result length by how much we've added to the string */ - *result_len += walkbuf - (result + *result_len); + result_len += walkbuf - (result->val + result_len); } if (limit != -1) @@ -1181,26 +1178,23 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub if (g_notempty != 0 && start_offset < subject_len) { offsets[0] = start_offset; offsets[1] = start_offset + 1; - memcpy(&result[*result_len], piece, 1); - (*result_len)++; + memcpy(&result->val[result_len], piece, 1); + result_len++; } else { - new_len = *result_len + subject_len - start_offset; - if (new_len + 1 > alloc_len) { - alloc_len = new_len + 1; /* now we know exactly how long it is */ - new_buf = safe_emalloc(alloc_len, sizeof(char), 0); - memcpy(new_buf, result, *result_len); - efree(result); - result = new_buf; + new_len = result_len + subject_len - start_offset; + if (new_len > alloc_len) { + alloc_len = new_len; /* now we know exactly how long it is */ + result = STR_REALLOC(result, alloc_len, 0); } /* stick that last bit of string on our output */ - memcpy(&result[*result_len], piece, subject_len - start_offset); - *result_len += subject_len - start_offset; - result[*result_len] = '\0'; + memcpy(&result->val[result_len], piece, subject_len - start_offset); + result_len += subject_len - start_offset; + result->val[result_len] = '\0'; break; } } else { pcre_handle_exec_error(count TSRMLS_CC); - efree(result); + STR_FREE(result); result = NULL; break; } @@ -1215,6 +1209,9 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub start_offset = offsets[1]; } + if (result) { + result->len = result_len; + } efree(offsets); efree(subpat_names); @@ -1224,15 +1221,14 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub /* {{{ php_replace_in_subject */ -static char *php_replace_in_subject(zval *regex, zval *replace, zval *subject, int *result_len, int limit, int is_callable_replace, int *replace_count TSRMLS_DC) +static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *subject, int limit, int is_callable_replace, int *replace_count TSRMLS_DC) { zval *regex_entry, *replace_entry = NULL, *replace_value, empty_replace; - char *subject_value, - *result; - int subject_len; + zend_string *subject_value; + zend_string *result; /* Make sure we're dealing with strings. */ convert_to_string_ex(subject); @@ -1243,9 +1239,7 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval *subject, i /* If regex is an array */ if (Z_TYPE_P(regex) == IS_ARRAY) { /* Duplicate subject string for repeated replacement */ - subject_value = estrndup(Z_STRVAL_P(subject), Z_STRLEN_P(subject)); - subject_len = Z_STRLEN_P(subject); - *result_len = subject_len; + subject_value = STR_INIT(Z_STRVAL_P(subject), Z_STRLEN_P(subject), 0); zend_hash_internal_pointer_reset(Z_ARRVAL_P(regex)); @@ -1276,18 +1270,16 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval *subject, i /* Do the actual replacement and put the result back into subject_value for further replacements. */ if ((result = php_pcre_replace(Z_STR_P(regex_entry), - subject_value, - subject_len, + subject_value->val, + subject_value->len, replace_value, is_callable_replace, - result_len, limit, replace_count TSRMLS_CC)) != NULL) { - efree(subject_value); + STR_RELEASE(subject_value); subject_value = result; - subject_len = *result_len; } else { - efree(subject_value); + STR_RELEASE(subject_value); return NULL; } @@ -1301,7 +1293,6 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval *subject, i Z_STRLEN_P(subject), replace, is_callable_replace, - result_len, limit, replace_count TSRMLS_CC); return result; @@ -1318,10 +1309,9 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl *subject, *subject_entry, *zcount = NULL; - char *result; - int result_len; int limit_val = -1; - long limit = -1; + long limit = -1; + zend_string *result; zend_string *string_key; ulong num_key; zend_string *callback_name; @@ -1371,24 +1361,21 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl while ((subject_entry = zend_hash_get_current_data(Z_ARRVAL_P(subject))) != NULL) { SEPARATE_ZVAL(subject_entry); old_replace_count = replace_count; - if ((result = php_replace_in_subject(regex, replace, subject_entry, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { + if ((result = php_replace_in_subject(regex, replace, subject_entry, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { /* Add to return array */ switch(zend_hash_get_current_key_ex(Z_ARRVAL_P(subject), &string_key, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: -//??? - add_assoc_stringl_ex(return_value, string_key->val, string_key->len, result, result_len, 0); - efree(result); + add_assoc_str_ex(return_value, string_key->val, string_key->len, result); break; case HASH_KEY_IS_LONG: - add_index_stringl(return_value, num_key, result, result_len, 0); - efree(result); + add_index_str(return_value, num_key, result); break; } } else { - efree(result); + STR_FREE(result); } } @@ -1396,14 +1383,11 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl } } else { /* if subject is not an array */ old_replace_count = replace_count; - if ((result = php_replace_in_subject(regex, replace, subject, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { + if ((result = php_replace_in_subject(regex, replace, subject, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { -//??? TODO: reimpplement to avoid double reallocation -//??? RETVAL_STRINGL(result, result_len, 0); - RETVAL_STRINGL(result, result_len); - efree(result); + RETVAL_STR(result); } else { - efree(result); + STR_FREE(result); } } } @@ -1791,7 +1775,11 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) { zval subject; - ZVAL_COPY_VALUE(&subject, entry); + if (Z_TYPE_P(entry) == IS_REFERENCE) { + entry = Z_REFVAL_P(entry); + } + + ZVAL_COPY_VALUE(&subject, entry); if (Z_TYPE_P(entry) != IS_STRING) { zval_copy_ctor(&subject); -- cgit v1.2.1 From 412ca11eda7f15415f1bca0cf72e15f125ce404d Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 16 Mar 2014 08:45:43 +0800 Subject: Fixed reference arg hanlding in pcre_replace --- ext/pcre/php_pcre.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 3c60a6a3e4..969fce2e9e 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1392,6 +1392,9 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl } } if (ZEND_NUM_ARGS() > 4) { + if (Z_ISREF_P(zcount)) { + zcount = Z_REFVAL_P(zcount); + } zval_dtor(zcount); ZVAL_LONG(zcount, replace_count); } -- cgit v1.2.1 From bf5e00f2e61cbfd2f728d61655fe393be4890299 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 16 Mar 2014 15:40:35 +0800 Subject: Fixed reference handling in pcre_grep --- ext/pcre/php_pcre.c | 10 ++++++++-- 1 file changed, 8 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 969fce2e9e..3298f52fb3 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1776,9 +1776,10 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return /* Go through the input array */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) { - zval subject; + zval subject, *ref_entry = NULL; if (Z_TYPE_P(entry) == IS_REFERENCE) { + ref_entry = entry; entry = Z_REFVAL_P(entry); } @@ -1806,7 +1807,12 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return /* If the entry fits our requirements */ if ((count > 0 && !invert) || (count == PCRE_ERROR_NOMATCH && invert)) { - if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry); + if (ref_entry) { + Z_ADDREF_P(ref_entry); + entry = ref_entry; + } else if (Z_REFCOUNTED_P(entry)) { + Z_ADDREF_P(entry); + } /* Add to return array */ switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, NULL)) -- cgit v1.2.1 From 54d559d893f07098e56bee4489d514726dc96f7d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Mar 2014 11:50:45 +0400 Subject: Replaced (Z_TYPE(x) == IS_REFERENCE) with (Z_ISREF(x)) --- 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 3298f52fb3..d03198cf6c 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -539,7 +539,7 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * RETURN_FALSE; } - if (subpats && Z_TYPE_P(subpats) == IS_REFERENCE) { + if (subpats && Z_ISREF_P(subpats)) { subpats = Z_REFVAL_P(subpats); } php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, @@ -1778,7 +1778,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) { zval subject, *ref_entry = NULL; - if (Z_TYPE_P(entry) == IS_REFERENCE) { + if (Z_ISREF_P(entry)) { ref_entry = entry; entry = Z_REFVAL_P(entry); } -- cgit v1.2.1 From c6cba554544d9dc676d1cfa99447364c95768664 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Mar 2014 13:39:09 +0400 Subject: Use ZVAL_DEREF() macro --- ext/pcre/php_pcre.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index d03198cf6c..9cc7815fa1 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -539,8 +539,8 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * RETURN_FALSE; } - if (subpats && Z_ISREF_P(subpats)) { - subpats = Z_REFVAL_P(subpats); + if (subpats) { + ZVAL_DEREF_REF(subpats); } php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, global, ZEND_NUM_ARGS() >= 4, flags, start_offset TSRMLS_CC); @@ -1392,9 +1392,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl } } if (ZEND_NUM_ARGS() > 4) { - if (Z_ISREF_P(zcount)) { - zcount = Z_REFVAL_P(zcount); - } + ZVAL_DEREF_REF(zcount); zval_dtor(zcount); ZVAL_LONG(zcount, replace_count); } -- cgit v1.2.1 From dccd97d347c9dea6a43201ea002f5e74e845a831 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 1 Apr 2014 23:44:42 +0400 Subject: Avoid unnecessary zval separations --- ext/pcre/php_pcre.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 9cc7815fa1..da691287b9 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1231,7 +1231,11 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub zend_string *result; /* Make sure we're dealing with strings. */ - convert_to_string_ex(subject); + if (Z_TYPE_P(subject) != IS_STRING) { + SEPARATE_ZVAL(subject); + 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); ZVAL_EMPTY_STRING(&empty_replace); @@ -1327,8 +1331,8 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl RETURN_FALSE; } - SEPARATE_ZVAL(replace); 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 (is_callable_replace) { @@ -1341,16 +1345,15 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl STR_RELEASE(callback_name); } - SEPARATE_ZVAL(regex); - SEPARATE_ZVAL(subject); - if (ZEND_NUM_ARGS() > 3) { limit_val = limit; } - if (Z_TYPE_P(regex) != IS_ARRAY) + if (Z_TYPE_P(regex) != IS_ARRAY) { + SEPARATE_ZVAL(regex); convert_to_string_ex(regex); - + } + /* if subject is an array */ if (Z_TYPE_P(subject) == IS_ARRAY) { array_init(return_value); @@ -1359,7 +1362,6 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl /* For each subject entry, convert it to string, then perform replacement and add the result to the return_value array. */ while ((subject_entry = zend_hash_get_current_data(Z_ARRVAL_P(subject))) != NULL) { - SEPARATE_ZVAL(subject_entry); old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject_entry, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { -- cgit v1.2.1 From 7240b4ec4d31d61abcc97c315a826cfaf91ce188 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Apr 2014 01:56:16 +0400 Subject: Avoid unnecessary zval separations --- ext/pcre/php_pcre.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index da691287b9..eb77a39cb3 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1226,14 +1226,20 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub zval *regex_entry, *replace_entry = NULL, *replace_value, + tmp_subject, empty_replace; zend_string *subject_value; zend_string *result; - /* Make sure we're dealing with strings. */ + /* Make sure we're dealing with strings. */ + if (Z_ISREF_P(subject)) { + subject = Z_REFVAL_P(subject); + } + ZVAL_UNDEF(&tmp_subject); if (Z_TYPE_P(subject) != IS_STRING) { - SEPARATE_ZVAL(subject); - convert_to_string_ex(subject); + ZVAL_DUP(&tmp_subject, subject); + convert_to_string_ex(&tmp_subject); + subject = &tmp_subject; } /* FIXME: This might need to be changed to STR_EMPTY_ALLOC(). Check if this zval could be dtor()'ed somehow */ @@ -1284,12 +1290,14 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub subject_value = result; } else { STR_RELEASE(subject_value); + zval_ptr_dtor(&tmp_subject); return NULL; } zend_hash_move_forward(Z_ARRVAL_P(regex)); } + zval_ptr_dtor(&tmp_subject); return subject_value; } else { result = php_pcre_replace(Z_STR_P(regex), @@ -1299,6 +1307,7 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub is_callable_replace, limit, replace_count TSRMLS_CC); + zval_ptr_dtor(&tmp_subject); return result; } } -- cgit v1.2.1 From 3d17219cd88a73306acd6eeff8cbae02868318c6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 7 Apr 2014 23:14:17 +0400 Subject: Refactored zend_hash_* iteration API zend_hash_fove_forward_ex(ht, pos) and family require second argument to be real pointer. &(ht)->nInternalPointer should be passed instead of NULL. zend_hash_update_current_key() may work only with internal pointer. --- 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 eb77a39cb3..2c228f0230 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1375,7 +1375,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl if ((result = php_replace_in_subject(regex, replace, subject_entry, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { /* Add to return array */ - switch(zend_hash_get_current_key_ex(Z_ARRVAL_P(subject), &string_key, &num_key, 0, NULL)) + switch(zend_hash_get_current_key(Z_ARRVAL_P(subject), &string_key, &num_key, 0)) { case HASH_KEY_IS_STRING: add_assoc_str_ex(return_value, string_key->val, string_key->len, result); @@ -1824,7 +1824,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return } /* Add to return array */ - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, NULL)) + switch (zend_hash_get_current_key(Z_ARRVAL_P(input), &string_key, &num_key, 0)) { case HASH_KEY_IS_STRING: zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); -- cgit v1.2.1 From 050d7e38ad4163e7fa65e26724d3516ce7b33601 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 15 Apr 2014 15:40:40 +0400 Subject: Cleanup (1-st round) --- ext/pcre/php_pcre.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 2c228f0230..bd76b556af 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -507,7 +507,7 @@ static inline void add_offset_pair(zval *result, char *str, int len, int offset, array_init(&match_pair); /* Add (match, offset) to the return value */ - add_next_index_stringl(&match_pair, str, len, 1); + add_next_index_stringl(&match_pair, str, len); add_next_index_long(&match_pair, offset); if (name) { @@ -540,7 +540,7 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ * } if (subpats) { - ZVAL_DEREF_REF(subpats); + ZVAL_DEREF(subpats); } php_pcre_match_impl(pce, subject, subject_len, return_value, subpats, global, ZEND_NUM_ARGS() >= 4, flags, start_offset TSRMLS_CC); @@ -682,7 +682,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec offsets[(i<<1)+1] - offsets[i<<1], offsets[i<<1], NULL); } else { add_next_index_stringl(&match_sets[i], (char *)stringlist[i], - offsets[(i<<1)+1] - offsets[i<<1], 1); + offsets[(i<<1)+1] - offsets[i<<1]); } } /* @@ -692,7 +692,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec */ if (count < num_subpats) { for (; i < num_subpats; i++) { - add_next_index_string(&match_sets[i], "", 1); + add_next_index_string(&match_sets[i], ""); } } } else { @@ -707,10 +707,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec } else { if (subpat_names[i]) { add_assoc_stringl(&result_set, subpat_names[i], (char *)stringlist[i], - offsets[(i<<1)+1] - offsets[i<<1], 1); + offsets[(i<<1)+1] - offsets[i<<1]); } add_next_index_stringl(&result_set, (char *)stringlist[i], - offsets[(i<<1)+1] - offsets[i<<1], 1); + offsets[(i<<1)+1] - offsets[i<<1]); } } /* And add it to the output array */ @@ -726,10 +726,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec } else { if (subpat_names[i]) { add_assoc_stringl(subpats, subpat_names[i], (char *)stringlist[i], - offsets[(i<<1)+1] - offsets[i<<1], 1); + offsets[(i<<1)+1] - offsets[i<<1]); } add_next_index_stringl(subpats, (char *)stringlist[i], - offsets[(i<<1)+1] - offsets[i<<1], 1); + offsets[(i<<1)+1] - offsets[i<<1]); } } } @@ -853,9 +853,9 @@ static int preg_do_repl_func(zval *function, char *subject, int *offsets, char * array_init(&args[0]); for (i = 0; i < count; i++) { if (subpat_names[i]) { - add_assoc_stringl(&args[0], subpat_names[i], &subject[offsets[i<<1]] , offsets[(i<<1)+1] - offsets[i<<1], 1); + add_assoc_stringl(&args[0], subpat_names[i], &subject[offsets[i<<1]] , offsets[(i<<1)+1] - offsets[i<<1]); } - add_next_index_stringl(&args[0], &subject[offsets[i<<1]], offsets[(i<<1)+1] - offsets[i<<1], 1); + add_next_index_stringl(&args[0], &subject[offsets[i<<1]], offsets[(i<<1)+1] - offsets[i<<1]); } if (call_user_function_ex(EG(function_table), NULL, function, &retval, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { @@ -1403,7 +1403,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl } } if (ZEND_NUM_ARGS() > 4) { - ZVAL_DEREF_REF(zcount); + ZVAL_DEREF(zcount); zval_dtor(zcount); ZVAL_LONG(zcount, replace_count); } @@ -1541,7 +1541,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec } else { /* Add the piece to the return value */ add_next_index_stringl(return_value, last_match, - &subject[offsets[0]]-last_match, 1); + &subject[offsets[0]]-last_match); } /* One less left to do */ @@ -1563,7 +1563,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec } else { add_next_index_stringl(return_value, &subject[offsets[i<<1]], - match_len, 1); + match_len); } } } @@ -1622,7 +1622,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec add_offset_pair(return_value, &subject[start_offset], subject_len - start_offset, start_offset, NULL); } else { /* Add the last piece to the return value */ - add_next_index_stringl(return_value, last_match, subject + subject_len - last_match, 1); + add_next_index_stringl(return_value, last_match, subject + subject_len - last_match); } } -- cgit v1.2.1 From f9b26bc39a9ea9b1380628eeb0e6dad3c93cfcb0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 15 Apr 2014 21:56:30 +0400 Subject: Cleanup (2-nd round) --- ext/pcre/php_pcre.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index bd76b556af..54f7667d0f 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1243,7 +1243,6 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub } /* 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); ZVAL_EMPTY_STRING(&empty_replace); /* If regex is an array */ -- cgit v1.2.1 From d0cc5c633c3eeaa61fe1108e74ba9c5941e580c0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 15 Apr 2014 22:10:39 +0400 Subject: Use zend_string* instead of char* --- ext/pcre/php_pcre.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 54f7667d0f..1527fff30d 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1640,8 +1640,8 @@ static PHP_FUNCTION(preg_quote) char *in_str_end; /* End of the input string */ int delim_len = 0; char *delim = NULL; /* Additional delimiter argument */ - char *out_str, /* Output string with quoted characters */ - *p, /* Iterator for input string */ + zend_string *out_str; /* Output string with quoted characters */ + char *p, /* Iterator for input string */ *q, /* Iterator for output string */ delim_char=0, /* Delimiter character to be quoted */ c; /* Current character */ @@ -1667,10 +1667,10 @@ static PHP_FUNCTION(preg_quote) /* 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); + out_str = STR_SAFE_ALLOC(4, in_str_len, 0, 0); /* Go through the string and quote necessary characters */ - for(p = in_str, q = out_str; p != in_str_end; p++) { + for (p = in_str, q = out_str->val; p != in_str_end; p++) { c = *p; switch(c) { case '.': @@ -1712,11 +1712,10 @@ 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); - RETVAL_STRINGL(out_str, q - out_str); - efree(out_str); + out_str = STR_REALLOC(out_str, q - out_str->val, 0); + RETURN_STR(out_str); } /* }}} */ -- cgit v1.2.1 From 81b24d4100bf229844e4980c79f27763827f10d2 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 16 Apr 2014 12:08:16 +0400 Subject: Fixed reference support --- ext/pcre/php_pcre.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 1527fff30d..a38c5cdebd 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1783,10 +1783,9 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return /* Go through the input array */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) { - zval subject, *ref_entry = NULL; + zval subject, *ref_entry = entry; if (Z_ISREF_P(entry)) { - ref_entry = entry; entry = Z_REFVAL_P(entry); } @@ -1814,22 +1813,19 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return /* If the entry fits our requirements */ if ((count > 0 && !invert) || (count == PCRE_ERROR_NOMATCH && invert)) { - if (ref_entry) { + if (Z_REFCOUNTED_P(ref_entry)) { Z_ADDREF_P(ref_entry); - entry = ref_entry; - } else if (Z_REFCOUNTED_P(entry)) { - Z_ADDREF_P(entry); } /* Add to return array */ switch (zend_hash_get_current_key(Z_ARRVAL_P(input), &string_key, &num_key, 0)) { case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); + zend_hash_update(Z_ARRVAL_P(return_value), string_key, ref_entry); break; case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, ref_entry); break; } } -- cgit v1.2.1 From 7652a977a88b825f66959e91a7c8c54b720a50bc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 18 Apr 2014 19:18:11 +0400 Subject: Use ZEND_FETCH_FOREACH_* macros to iterate over HashTables instead of zend_hash_move_forward() and family. --- ext/pcre/php_pcre.c | 44 +++++++++++++------------------------------- 1 file changed, 13 insertions(+), 31 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index a38c5cdebd..724b667bde 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1250,14 +1250,12 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub /* Duplicate subject string for repeated replacement */ subject_value = STR_INIT(Z_STRVAL_P(subject), Z_STRLEN_P(subject), 0); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(regex)); - replace_value = replace; if (Z_TYPE_P(replace) == IS_ARRAY && !is_callable_replace) zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace)); /* For each entry in the regex array, get the entry */ - while ((regex_entry = zend_hash_get_current_data(Z_ARRVAL_P(regex))) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(regex), regex_entry) { /* Make sure we're dealing with strings. */ convert_to_string_ex(regex_entry); @@ -1293,8 +1291,7 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub return NULL; } - zend_hash_move_forward(Z_ARRVAL_P(regex)); - } + } ZEND_HASH_FOREACH_END(); zval_ptr_dtor(&tmp_subject); return subject_value; @@ -1365,32 +1362,24 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl /* if subject is an array */ if (Z_TYPE_P(subject) == IS_ARRAY) { array_init(return_value); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(subject)); /* For each subject entry, convert it to string, then perform replacement and add the result to the return_value array. */ - while ((subject_entry = zend_hash_get_current_data(Z_ARRVAL_P(subject))) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(subject), num_key, string_key, subject_entry) { old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject_entry, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { /* Add to return array */ - switch(zend_hash_get_current_key(Z_ARRVAL_P(subject), &string_key, &num_key, 0)) - { - case HASH_KEY_IS_STRING: + if (string_key) { add_assoc_str_ex(return_value, string_key->val, string_key->len, result); - break; - - case HASH_KEY_IS_LONG: + } else { add_index_str(return_value, num_key, result); - break; } } else { STR_FREE(result); } } - - zend_hash_move_forward(Z_ARRVAL_P(subject)); - } + } ZEND_HASH_FOREACH_END(); } else { /* if subject is not an array */ old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { @@ -1781,8 +1770,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return PCRE_G(error_code) = PHP_PCRE_NO_ERROR; /* Go through the input array */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); - while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) { zval subject, *ref_entry = entry; if (Z_ISREF_P(entry)) { @@ -1818,15 +1806,10 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return } /* Add to return array */ - switch (zend_hash_get_current_key(Z_ARRVAL_P(input), &string_key, &num_key, 0)) - { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, ref_entry); - break; - - case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, ref_entry); - break; + if (string_key) { + zend_hash_update(Z_ARRVAL_P(return_value), string_key, ref_entry); + } else { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, ref_entry); } } @@ -1834,9 +1817,8 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return zval_dtor(&subject); } - zend_hash_move_forward(Z_ARRVAL_P(input)); - } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); + } ZEND_HASH_FOREACH_END(); + /* Clean up */ efree(offsets); } -- cgit v1.2.1 From 5864ce8a447b718d0912cb073afe87eddc47b2e8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 22 Apr 2014 17:46:34 +0400 Subject: Fixed compilation warnings --- 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 724b667bde..60769f1314 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1008,7 +1008,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, *match, /* The current match */ *piece, /* The current piece of subject */ *replace_end=NULL, /* End of replacement string */ - *eval_result, /* Result of eval or custom function */ + *eval_result=NULL, /* Result of eval or custom function */ walk_last; /* Last walked character */ int rc, result_len; /* Length of result */ -- cgit v1.2.1 From d0ed1212a454dbbae7ec0327bc4f063e26037a0b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 25 Apr 2014 08:33:37 +0400 Subject: Enable PCRE JIT compiler --- ext/pcre/php_pcre.c | 15 ++++++++++++++- 1 file changed, 14 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 60769f1314..983dd6d4fc 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -117,7 +117,10 @@ static PHP_GSHUTDOWN_FUNCTION(pcre) /* {{{ */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("pcre.backtrack_limit", "1000000", PHP_INI_ALL, OnUpdateLong, backtrack_limit, zend_pcre_globals, pcre_globals) - STD_PHP_INI_ENTRY("pcre.recursion_limit", "100000", PHP_INI_ALL, OnUpdateLong, recursion_limit, zend_pcre_globals, pcre_globals) + STD_PHP_INI_ENTRY("pcre.recursion_limit", "100000", PHP_INI_ALL, OnUpdateLong, recursion_limit, zend_pcre_globals, pcre_globals) +#ifdef PCRE_STUDY_JIT_COMPILE + STD_PHP_INI_ENTRY("pcre.jit", "1", PHP_INI_ALL, OnUpdateBool, jit, zend_pcre_globals, pcre_globals) +#endif PHP_INI_END() @@ -412,12 +415,22 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex TSRMLS return NULL; } +#ifdef PCRE_STUDY_JIT_COMPILE + if (PCRE_G(jit)) { + /* Enable PCRE JIT compiler */ + do_study = 1; + soptions |= PCRE_STUDY_JIT_COMPILE; + } +#endif + /* If study option was specified, study the pattern and store the result in extra for passing to pcre_exec. */ if (do_study) { extra = pcre_study(re, soptions, &error); if (extra) { extra->flags |= PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION; + extra->match_limit = PCRE_G(backtrack_limit); + extra->match_limit_recursion = PCRE_G(recursion_limit); } if (error != NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while studying pattern"); -- cgit v1.2.1 From f979e9afb0f9271e0677f65905bfc26759d91e00 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 25 Apr 2014 12:32:30 +0200 Subject: More zend_string usage in PCRE Avoid a few copies and zval duplications --- ext/pcre/php_pcre.c | 129 +++++++++++++++++++--------------------------------- 1 file changed, 47 insertions(+), 82 deletions(-) (limited to 'ext/pcre/php_pcre.c') diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index b815667238..636bafae15 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -883,11 +883,11 @@ static int preg_get_backref(char **str, int *backref) /* {{{ preg_do_repl_func */ -static int preg_do_repl_func(zval *function, char *subject, int *offsets, char **subpat_names, int count, unsigned char *mark, char **result TSRMLS_DC) +static zend_string *preg_do_repl_func(zval *function, char *subject, int *offsets, char **subpat_names, int count, unsigned char *mark TSRMLS_DC) { + zend_string *result_str; zval retval; /* Function return value */ zval args[1]; /* Argument to pass to function */ - int result_len; /* Return value length */ int i; array_init(&args[0]); @@ -902,28 +902,26 @@ static int preg_do_repl_func(zval *function, char *subject, int *offsets, char * } if (call_user_function_ex(EG(function_table), NULL, function, &retval, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { - convert_to_string_ex(&retval); - *result = estrndup(Z_STRVAL(retval), Z_STRLEN(retval)); - result_len = Z_STRLEN(retval); + result_str = zval_get_string(&retval); zval_ptr_dtor(&retval); } else { if (!EG(exception)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call custom replacement function"); } - result_len = offsets[1] - offsets[0]; - *result = estrndup(&subject[offsets[0]], result_len); + + result_str = STR_INIT(&subject[offsets[0]], offsets[1] - offsets[0], 0); } zval_ptr_dtor(&args[0]); - return result_len; + return result_str; } /* }}} */ /* {{{ preg_do_eval */ -static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, - int *offsets, int count, char **result TSRMLS_DC) +static zend_string *preg_do_eval(char *eval_str, int eval_str_len, char *subject, + int *offsets, int count TSRMLS_DC) { zval retval; /* Return value from evaluation */ char *eval_str_end, /* End of eval string */ @@ -932,9 +930,9 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, *segment, /* Start of segment to append while walking */ walk_last; /* Last walked character */ int match_len; /* Length of the match */ - int result_len; /* Length of the result of the evaluation */ int backref; /* Current backref */ zend_string *esc_match; /* Quote-escaped match */ + zend_string *result_str; char *compiled_string_description; smart_str code = {0}; @@ -990,17 +988,15 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, /* zend_error() does not return in this case */ } 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); + /* Save the return string */ + result_str = zval_get_string(&retval); /* Clean up */ zval_dtor(&retval); smart_str_free(&code); - return result_len; + return result_str; } /* }}} */ @@ -1037,8 +1033,6 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int size_offsets; /* Size of the offsets array */ int new_len; /* Length of needed storage */ int alloc_len; /* Actual allocated length */ - int eval_result_len=0; /* Length of the eval'ed or - function-returned string */ int match_len; /* Length of the current match */ int backref; /* Backreference number */ int eval; /* If the replacement string should be eval'ed */ @@ -1051,12 +1045,12 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, *match, /* The current match */ *piece, /* The current piece of subject */ *replace_end=NULL, /* End of replacement string */ - *eval_result=NULL, /* Result of eval or custom function */ walk_last; /* Last walked character */ int rc, result_len; /* Length of result */ unsigned char *mark = NULL; /* Target for MARK name */ zend_string *result; /* Result of replacement */ + zend_string *eval_result=NULL; /* Result of eval or custom function */ if (extra == NULL) { extra_data.flags = PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION; @@ -1142,13 +1136,13 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, /* If evaluating, do it and add the return string's length */ if (eval) { - eval_result_len = preg_do_eval(replace, replace_len, subject, - offsets, count, &eval_result TSRMLS_CC); - new_len += eval_result_len; + eval_result = preg_do_eval(replace, replace_len, subject, + offsets, count TSRMLS_CC); + new_len += eval_result->len; } else if (is_callable_replace) { /* Use custom function to get replacement string and its length. */ - eval_result_len = preg_do_repl_func(replace_val, subject, offsets, subpat_names, count, mark, &eval_result TSRMLS_CC); - new_len += eval_result_len; + eval_result = preg_do_repl_func(replace_val, subject, offsets, subpat_names, count, mark TSRMLS_CC); + new_len += eval_result->len; } else { /* do regular substitution */ walk = replace; walk_last = 0; @@ -1185,9 +1179,9 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, /* If evaluating or using custom function, copy result to the buffer * and clean up. */ if (eval || is_callable_replace) { - memcpy(walkbuf, eval_result, eval_result_len); - result_len += eval_result_len; - if (eval_result) efree(eval_result); + memcpy(walkbuf, eval_result->val, eval_result->len); + result_len += eval_result->len; + if (eval_result) STR_RELEASE(eval_result); } else { /* do regular backreference copying */ walk = replace; walk_last = 0; @@ -1274,30 +1268,15 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub zval *regex_entry, *replace_entry = NULL, *replace_value, - tmp_subject, empty_replace; - zend_string *subject_value; zend_string *result; - - /* Make sure we're dealing with strings. */ - if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - } - ZVAL_UNDEF(&tmp_subject); - if (Z_TYPE_P(subject) != IS_STRING) { - ZVAL_DUP(&tmp_subject, subject); - convert_to_string_ex(&tmp_subject); - subject = &tmp_subject; - } + zend_string *subject_str = zval_get_string(subject); /* FIXME: This might need to be changed to STR_EMPTY_ALLOC(). Check if this zval could be dtor()'ed somehow */ ZVAL_EMPTY_STRING(&empty_replace); /* If regex is an array */ if (Z_TYPE_P(regex) == IS_ARRAY) { - /* Duplicate subject string for repeated replacement */ - subject_value = STR_INIT(Z_STRVAL_P(subject), Z_STRLEN_P(subject), 0); - replace_value = replace; if (Z_TYPE_P(replace) == IS_ARRAY && !is_callable_replace) zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace)); @@ -1305,7 +1284,7 @@ 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) { /* Make sure we're dealing with strings. */ - convert_to_string_ex(regex_entry); + zend_string *regex_str = zval_get_string(regex_entry); /* If replace is an array and not a callable construct */ if (Z_TYPE_P(replace) == IS_ARRAY && !is_callable_replace) { @@ -1322,36 +1301,36 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub } } - /* Do the actual replacement and put the result back into subject_value + /* Do the actual replacement and put the result back into subject_str for further replacements. */ - if ((result = php_pcre_replace(Z_STR_P(regex_entry), - subject_value->val, - subject_value->len, + if ((result = php_pcre_replace(regex_str, + subject_str->val, + subject_str->len, replace_value, is_callable_replace, limit, replace_count TSRMLS_CC)) != NULL) { - STR_RELEASE(subject_value); - subject_value = result; + STR_RELEASE(subject_str); + subject_str = result; } else { - STR_RELEASE(subject_value); - zval_ptr_dtor(&tmp_subject); + STR_RELEASE(subject_str); + STR_RELEASE(regex_str); return NULL; } + STR_RELEASE(regex_str); } ZEND_HASH_FOREACH_END(); - zval_ptr_dtor(&tmp_subject); - return subject_value; + return subject_str; } else { result = php_pcre_replace(Z_STR_P(regex), - Z_STRVAL_P(subject), - Z_STRLEN_P(subject), + subject_str->val, + subject_str->len, replace, is_callable_replace, limit, replace_count TSRMLS_CC); - zval_ptr_dtor(&tmp_subject); + STR_RELEASE(subject_str); return result; } } @@ -1424,7 +1403,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl add_index_str(return_value, num_key, result); } } else { - STR_FREE(result); + STR_RELEASE(result); } } } ZEND_HASH_FOREACH_END(); @@ -1434,7 +1413,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl if (!is_filter || replace_count > old_replace_count) { RETVAL_STR(result); } else { - STR_FREE(result); + STR_RELEASE(result); } } } @@ -1825,22 +1804,11 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return /* Go through the input array */ ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) { - zval subject, *ref_entry = entry; - - if (Z_ISREF_P(entry)) { - entry = Z_REFVAL_P(entry); - } - - ZVAL_COPY_VALUE(&subject, entry); - - if (Z_TYPE_P(entry) != IS_STRING) { - zval_copy_ctor(&subject); - convert_to_string(&subject); - } + zend_string *subject_str = zval_get_string(entry); /* Perform the match */ - count = pcre_exec(pce->re, extra, Z_STRVAL(subject), - Z_STRLEN(subject), 0, + count = pcre_exec(pce->re, extra, subject_str->val, + subject_str->len, 0, 0, offsets, size_offsets); /* Check for too many substrings condition. */ @@ -1849,28 +1817,25 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return count = size_offsets/3; } else if (count < 0 && count != PCRE_ERROR_NOMATCH) { pcre_handle_exec_error(count TSRMLS_CC); + STR_RELEASE(subject_str); break; } /* If the entry fits our requirements */ if ((count > 0 && !invert) || (count == PCRE_ERROR_NOMATCH && invert)) { - - if (Z_REFCOUNTED_P(ref_entry)) { - Z_ADDREF_P(ref_entry); + if (Z_REFCOUNTED_P(entry)) { + Z_ADDREF_P(entry); } /* Add to return array */ if (string_key) { - zend_hash_update(Z_ARRVAL_P(return_value), string_key, ref_entry); + zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); } else { - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, ref_entry); + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); } } - if (Z_TYPE_P(entry) != IS_STRING) { - zval_dtor(&subject); - } - + STR_RELEASE(subject_str); } ZEND_HASH_FOREACH_END(); /* Clean up */ -- cgit v1.2.1