diff options
author | Xinchen Hui <laruence@php.net> | 2011-10-07 04:24:04 +0000 |
---|---|---|
committer | Xinchen Hui <laruence@php.net> | 2011-10-07 04:24:04 +0000 |
commit | c8ff0fe2542c296eda4e337a308ac9bb4e2df1ed (patch) | |
tree | 159e85a27642e68291fc59529ddd6322f3b6157a /ext/mbstring/php_mbregex.c | |
parent | 50bf7a11827b716bb86d2b8b4dafe04a6b06330f (diff) | |
download | php-git-c8ff0fe2542c296eda4e337a308ac9bb4e2df1ed.tar.gz |
Fix #55819 crash on mb_ereg_replace_callback
Need hirokawa to review this.
Diffstat (limited to 'ext/mbstring/php_mbregex.c')
-rw-r--r-- | ext/mbstring/php_mbregex.c | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 64db8396e8..f3fd96a556 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -793,11 +793,12 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp char *replace; int replace_len; - zval **arg_replace_zval; + + zend_fcall_info arg_replace_fci; + zend_fcall_info_cache arg_replace_fci_cache; char *string; int string_len; - zval **arg_string_zval; char *p; php_mb_regex_t *re; @@ -828,20 +829,24 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp char *option_str = NULL; int option_str_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|s", - &arg_pattern_zval, - &arg_replace_zval, - &arg_string_zval, - &option_str, &option_str_len) == FAILURE) { - RETURN_FALSE; + if (!is_callable) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zss|s", + &arg_pattern_zval, + &replace, &replace_len, + &string, &string_len, + &option_str, &option_str_len) == FAILURE) { + RETURN_FALSE; + } + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zfs|s", + &arg_pattern_zval, + &arg_replace_fci, &arg_replace_fci_cache, + &string, &string_len, + &option_str, &option_str_len) == FAILURE) { + RETURN_FALSE; + } } - replace = Z_STRVAL_PP(arg_replace_zval); - replace_len = Z_STRLEN_PP(arg_replace_zval); - - string = Z_STRVAL_PP(arg_string_zval); - string_len = Z_STRLEN_PP(arg_string_zval); - if (option_str != NULL) { _php_mb_regex_init_options(option_str, option_str_len, &options, &syntax, &eval); } else { @@ -876,15 +881,6 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp } if (is_callable) { - char *callback_name; - if (!zend_is_callable(*arg_replace_zval, 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); - MAKE_COPY_ZVAL(arg_string_zval, return_value); - RETURN_FALSE; - } - efree(callback_name); - if (eval) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Option 'e' cannot be used with replacement callback"); RETURN_FALSE; @@ -973,8 +969,10 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp /* null terminate buffer */ smart_str_0(&eval_buf); - if (call_user_function_ex(EG(function_table), NULL, *arg_replace_zval, &retval_ptr, 1, args, 0, - NULL TSRMLS_CC) == SUCCESS && retval_ptr) { + arg_replace_fci.param_count = 1; + arg_replace_fci.params = args; + arg_replace_fci.retval_ptr_ptr = &retval_ptr; + if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr) { convert_to_string_ex(&retval_ptr); smart_str_appendl(&out_buf, Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr)); eval_buf.len = 0; |