mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Fix preg_replace_callback_array() with array subject
Apparently this "feature" was completely untested...
This commit is contained in:
parent
da0663a337
commit
d81ea5e928
@ -2398,9 +2398,9 @@ PHP_FUNCTION(preg_replace_callback)
|
||||
/* {{{ Perform Perl-style regular expression replacement using replacement callback. */
|
||||
PHP_FUNCTION(preg_replace_callback_array)
|
||||
{
|
||||
zval zv, *replace, *subject, *zcount = NULL;
|
||||
HashTable *pattern;
|
||||
zend_string *str_idx_regex;
|
||||
zval zv, *replace, *zcount = NULL;
|
||||
HashTable *pattern, *subject_ht;
|
||||
zend_string *subject_str, *str_idx_regex;
|
||||
zend_long limit = -1, flags = 0;
|
||||
size_t replace_count = 0;
|
||||
zend_fcall_info fci;
|
||||
@ -2409,7 +2409,7 @@ PHP_FUNCTION(preg_replace_callback_array)
|
||||
/* Get function parameters and do error-checking. */
|
||||
ZEND_PARSE_PARAMETERS_START(2, 5)
|
||||
Z_PARAM_ARRAY_HT(pattern)
|
||||
Z_PARAM_ZVAL(subject)
|
||||
Z_PARAM_ARRAY_HT_OR_STR(subject_ht, subject_str)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_LONG(limit)
|
||||
Z_PARAM_ZVAL(zcount)
|
||||
@ -2420,41 +2420,66 @@ PHP_FUNCTION(preg_replace_callback_array)
|
||||
fci.object = NULL;
|
||||
fci.named_params = NULL;
|
||||
|
||||
if (subject_ht) {
|
||||
GC_TRY_ADDREF(subject_ht);
|
||||
} else {
|
||||
GC_TRY_ADDREF(subject_str);
|
||||
}
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(pattern, str_idx_regex, replace) {
|
||||
if (!str_idx_regex) {
|
||||
php_error_docref(NULL, E_WARNING, "Delimiter must not be alphanumeric or backslash");
|
||||
zval_ptr_dtor(return_value);
|
||||
RETURN_NULL();
|
||||
RETVAL_NULL();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!zend_is_callable_ex(replace, NULL, 0, NULL, &fcc, NULL)) {
|
||||
zend_argument_type_error(1, "must contain only valid callbacks");
|
||||
RETURN_THROWS();
|
||||
goto error;
|
||||
}
|
||||
|
||||
ZVAL_COPY_VALUE(&fci.function_name, replace);
|
||||
|
||||
replace_count += preg_replace_func_impl(&zv, str_idx_regex, /* regex_ht */ NULL, &fci, &fcc,
|
||||
Z_STR_P(subject), Z_ARRVAL_P(subject),
|
||||
limit, flags);
|
||||
|
||||
if (subject != return_value) {
|
||||
subject = return_value;
|
||||
} else {
|
||||
zval_ptr_dtor(return_value);
|
||||
subject_str, subject_ht, limit, flags);
|
||||
switch (Z_TYPE(zv)) {
|
||||
case IS_ARRAY:
|
||||
ZEND_ASSERT(subject_ht);
|
||||
zend_array_release(subject_ht);
|
||||
subject_ht = Z_ARR(zv);
|
||||
break;
|
||||
case IS_STRING:
|
||||
ZEND_ASSERT(subject_str);
|
||||
zend_string_release(subject_str);
|
||||
subject_str = Z_STR(zv);
|
||||
break;
|
||||
case IS_NULL:
|
||||
RETVAL_NULL();
|
||||
goto error;
|
||||
EMPTY_SWITCH_DEFAULT_CASE()
|
||||
}
|
||||
|
||||
ZVAL_COPY_VALUE(return_value, &zv);
|
||||
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
zval_ptr_dtor(return_value);
|
||||
RETURN_NULL();
|
||||
if (EG(exception)) {
|
||||
goto error;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (zcount) {
|
||||
ZEND_TRY_ASSIGN_REF_LONG(zcount, replace_count);
|
||||
}
|
||||
|
||||
if (subject_ht) {
|
||||
RETURN_ARR(subject_ht);
|
||||
} else {
|
||||
RETURN_STR(subject_str);
|
||||
}
|
||||
|
||||
error:
|
||||
if (subject_ht) {
|
||||
zend_array_release(subject_ht);
|
||||
} else {
|
||||
zend_string_release(subject_str);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -17,11 +17,8 @@ function preg_filter(string|array $regex, string|array $replace, string|array $s
|
||||
/** @param int $count */
|
||||
function preg_replace_callback(string|array $regex, callable $callback, string|array $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
|
||||
|
||||
/**
|
||||
* @param array|string $subject
|
||||
* @param int $count
|
||||
*/
|
||||
function preg_replace_callback_array(array $pattern, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
|
||||
/** @param int $count */
|
||||
function preg_replace_callback_array(array $pattern, string|array $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
|
||||
|
||||
function preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array|false {}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 8e8fea5b33408e8a1a39c1b1ae71f16fe1bdd391 */
|
||||
* Stub hash: 8270971708afa7fa9d82bec0f84c66cc8283f17d */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_match, 0, 2, MAY_BE_LONG|MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0)
|
||||
@ -38,7 +38,7 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_replace_callback_array, 0, 2, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL)
|
||||
ZEND_ARG_TYPE_INFO(0, pattern, IS_ARRAY, 0)
|
||||
ZEND_ARG_INFO(0, subject)
|
||||
ZEND_ARG_TYPE_MASK(0, subject, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1")
|
||||
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, count, "null")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
|
||||
|
@ -21,7 +21,5 @@ var_dump(preg_replace_callback_array(
|
||||
), 'a'));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %sbug73392.php on line %d
|
||||
|
||||
Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %sbug73392.php on line %d
|
||||
NULL
|
||||
|
@ -39,11 +39,21 @@ var_dump(preg_replace_callback_array(
|
||||
"/c/" => new Rep,
|
||||
"/a/" => 'b',
|
||||
"/b/" => function($a) { return "ok"; }), 'a', -1, $count));
|
||||
|
||||
var_dump($count);
|
||||
|
||||
var_dump(preg_replace_callback_array(
|
||||
array('/a/' => 'b', "/c/" => new Rep),
|
||||
array('a', 'c')));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(2) "ok"
|
||||
string(2) "ok"
|
||||
string(2) "ok"
|
||||
int(2)
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(1) "b"
|
||||
[1]=>
|
||||
string(1) "d"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user