Patch second_arg_rege_key.patch for Regexps related Bug #64730
Patch version 2013-05-04 12:35 UTC
Return to Bug #64730 |
Download this patch
Patch Revisions:
Developer: laruence@php.net
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 0c7280e..676c9d2 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -848,10 +848,10 @@ 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, char **result TSRMLS_DC)
+static int preg_do_repl_func(zval *function, zval* regex_key, char *subject, int *offsets, char **subpat_names, int count, char **result TSRMLS_DC)
{
zval *retval_ptr; /* Function return value */
- zval **args[1]; /* Argument to pass to function */
+ zval **args[2]; /* Argument to pass to function */
zval *subpats; /* Captured subpatterns */
int result_len; /* Return value length */
int i;
@@ -865,8 +865,16 @@ static int preg_do_repl_func(zval *function, char *subject, int *offsets, char *
add_next_index_stringl(subpats, &subject[offsets[i<<1]], offsets[(i<<1)+1] - offsets[i<<1], 1);
}
args[0] = &subpats;
+ if (!regex_key) {
+ zval *null_key;
+ MAKE_STD_ZVAL(null_key);
+ ZVAL_NULL(null_key);
+ args[1] = &null_key;
+ } else {
+ args[1] = ®ex_key;
+ }
- if (call_user_function_ex(EG(function_table), NULL, function, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) {
+ if (call_user_function_ex(EG(function_table), NULL, function, &retval_ptr, 2, args, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) {
convert_to_string_ex(&retval_ptr);
*result = estrndup(Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr));
result_len = Z_STRLEN_P(retval_ptr);
@@ -880,6 +888,9 @@ static int preg_do_repl_func(zval *function, char *subject, int *offsets, char *
}
zval_ptr_dtor(&subpats);
+ if (!regex_key) {
+ zval_ptr_dtor(args[1]);
+ }
return result_len;
}
@@ -980,6 +991,18 @@ PHPAPI char *php_pcre_replace(char *regex, int regex_len,
zval *replace_val, int is_callable_replace,
int *result_len, int limit, int *replace_count TSRMLS_DC)
{
+ return php_pcre_replace_ex(regex, regex_len, NULL, subject, subject_len,
+ replace_val, is_callable_replace, result_len, limit, replace_count TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ php_pcre_replace_ex
+ */
+PHPAPI char *php_pcre_replace_ex(char *regex, int regex_len, zval *regex_key,
+ char *subject, int subject_len,
+ zval *replace_val, int is_callable_replace,
+ int *result_len, int limit, int *replace_count TSRMLS_DC)
+{
pcre_cache_entry *pce; /* Compiled regular expression */
/* Compile regex or get it from cache. */
@@ -987,14 +1010,25 @@ PHPAPI char *php_pcre_replace(char *regex, int regex_len,
return NULL;
}
- return php_pcre_replace_impl(pce, subject, subject_len, replace_val,
- is_callable_replace, result_len, limit, replace_count TSRMLS_CC);
+ return php_pcre_replace_impl_ex(pce, regex_key, subject, subject_len, replace_val,
+ is_callable_replace, result_len, limit, replace_count TSRMLS_CC);
}
/* }}} */
-/* {{{ php_pcre_replace_impl() */
-PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *replace_val,
- int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC)
+/* {{{ 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)
+{
+ return php_pcre_replace_impl_ex(pce, NULL, subject, subject_len, replace_val,
+ is_callable_replace, result_len, limit, replace_count TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ php_pcre_replace_impl_ex
+ */
+PHPAPI char *php_pcre_replace_impl_ex(pcre_cache_entry *pce, zval *regex_key, char *subject, int subject_len,
+ zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC)
{
pcre_extra *extra = pce->extra;/* Holds results of studying */
pcre_extra extra_data; /* Used locally for exec options */
@@ -1111,7 +1145,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
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, &eval_result TSRMLS_CC);
+ eval_result_len = preg_do_repl_func(replace_val, regex_key, subject, offsets, subpat_names, count, &eval_result TSRMLS_CC);
new_len += eval_result_len;
} else { /* do regular substitution */
walk = replace;
@@ -1253,6 +1287,7 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject,
/* If regex is an array */
if (Z_TYPE_P(regex) == IS_ARRAY) {
+ zval *regex_key;
/* Duplicate subject string for repeated replacement */
subject_value = estrndup(Z_STRVAL_PP(subject), Z_STRLEN_PP(subject));
subject_len = Z_STRLEN_PP(subject);
@@ -1282,12 +1317,28 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject,
/* We've run out of replacement strings, so use an empty one */
replace_value = &empty_replace;
}
+ } else if (is_callable_replace) {
+ char *key;
+ ulong idx, key_len;
+ MAKE_STD_ZVAL(regex_key);
+ switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(regex), &key, &key_len, &idx, 0, NULL)) {
+ case HASH_KEY_IS_STRING:
+ ZVAL_STRINGL(regex_key, key, key_len, 1);
+ break;
+ case HASH_KEY_IS_LONG:
+ ZVAL_LONG(regex_key, idx);
+ break;
+ default:
+ ZVAL_NULL(regex_key);
+ break;
+ }
}
-
+
/* Do the actual replacement and put the result back into subject_value
for further replacements. */
- if ((result = php_pcre_replace(Z_STRVAL_PP(regex_entry),
+ if ((result = php_pcre_replace_ex(Z_STRVAL_PP(regex_entry),
Z_STRLEN_PP(regex_entry),
+ regex_key,
subject_value,
subject_len,
replace_value,
@@ -1299,10 +1350,17 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject,
subject_value = result;
subject_len = *result_len;
} else {
+ if (is_callable_replace) {
+ zval_ptr_dtor(®ex_key);
+ }
efree(subject_value);
return NULL;
}
+ if (is_callable_replace) {
+ zval_ptr_dtor(®ex_key);
+ }
+
zend_hash_move_forward(Z_ARRVAL_P(regex));
}
diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h
index d4acae0..9dd1cac 100644
--- a/ext/pcre/php_pcre.h
+++ b/ext/pcre/php_pcre.h
@@ -34,6 +34,7 @@
#endif
PHPAPI char *php_pcre_replace(char *regex, int regex_len, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
+PHPAPI char *php_pcre_replace_ex(char *regex, int regex_len, zval *regex_key, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *options TSRMLS_DC);
PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *coptions TSRMLS_DC);
@@ -60,6 +61,9 @@ PHPAPI void php_pcre_match_impl( pcre_cache_entry *pce, char *subject, int sub
PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
+PHPAPI char *php_pcre_replace_impl_ex(pcre_cache_entry *pce, zval *regex_key, char *subject, int subject_len,
+ zval *return_value, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
+
PHPAPI void php_pcre_split_impl( pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
long limit_val, long flags TSRMLS_DC);
|