Skip to content

Commit 1a2732f

Browse files
committed
Use ZPP callable check for preg_replace_callback() $callback argument
1 parent 26171c3 commit 1a2732f

File tree

4 files changed

+24
-32
lines changed

4 files changed

+24
-32
lines changed

ext/pcre/php_pcre.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2369,7 +2369,7 @@ PHP_FUNCTION(preg_replace)
23692369
Perform Perl-style regular expression replacement using replacement callback. */
23702370
PHP_FUNCTION(preg_replace_callback)
23712371
{
2372-
zval *regex, *replace, *subject, *zcount = NULL;
2372+
zval *regex, *subject, *zcount = NULL;
23732373
zend_long limit = -1, flags = 0;
23742374
size_t replace_count;
23752375
zend_fcall_info fci;
@@ -2378,26 +2378,14 @@ PHP_FUNCTION(preg_replace_callback)
23782378
/* Get function parameters and do error-checking. */
23792379
ZEND_PARSE_PARAMETERS_START(3, 6)
23802380
Z_PARAM_ZVAL(regex)
2381-
Z_PARAM_ZVAL(replace)
2381+
Z_PARAM_FUNC(fci, fcc)
23822382
Z_PARAM_ZVAL(subject)
23832383
Z_PARAM_OPTIONAL
23842384
Z_PARAM_LONG(limit)
23852385
Z_PARAM_ZVAL(zcount)
23862386
Z_PARAM_LONG(flags)
23872387
ZEND_PARSE_PARAMETERS_END();
23882388

2389-
if (!zend_is_callable_ex(replace, NULL, 0, NULL, &fcc, NULL)) {
2390-
zend_string *callback_name = zend_get_callable_name(replace);
2391-
php_error_docref(NULL, E_WARNING, "Requires argument 2, '%s', to be a valid callback", ZSTR_VAL(callback_name));
2392-
zend_string_release_ex(callback_name, 0);
2393-
ZVAL_STR(return_value, zval_get_string(subject));
2394-
return;
2395-
}
2396-
2397-
fci.size = sizeof(fci);
2398-
fci.object = NULL;
2399-
ZVAL_COPY_VALUE(&fci.function_name, replace);
2400-
24012389
replace_count = preg_replace_func_impl(return_value, regex, &fci, &fcc, subject, limit, flags);
24022390
if (zcount) {
24032391
ZEND_TRY_ASSIGN_REF_LONG(zcount, replace_count);

ext/pcre/php_pcre.stub.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ function preg_filter($regex, $replace, $subject, int $limit = -1, &$count = null
2323
/**
2424
* @param string|array $regex
2525
* @param string|array $subject
26-
*
27-
* TODO: $callback should be `callable`
2826
*/
29-
function preg_replace_callback($regex, $callback, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
27+
function preg_replace_callback($regex, callable $callback, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
3028

3129
/** @param string|array $subject */
3230
function preg_replace_callback_array(array $pattern, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}

ext/pcre/php_pcre_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ ZEND_END_ARG_INFO()
2828

2929
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_replace_callback, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL)
3030
ZEND_ARG_INFO(0, regex)
31-
ZEND_ARG_INFO(0, callback)
31+
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
3232
ZEND_ARG_INFO(0, subject)
3333
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1")
3434
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, count, "null")

ext/pcre/tests/preg_replace_callback3.phpt

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,26 @@ preg_replace_callback() 3
33
--FILE--
44
<?php
55

6-
var_dump(preg_replace_callback(1,2,3));
7-
var_dump(preg_replace_callback(1,2,3,4));
6+
try {
7+
var_dump(preg_replace_callback(1,2,3));
8+
} catch (\TypeError $e) {
9+
echo $e->getMessage() . \PHP_EOL;
10+
}
11+
try {
12+
var_dump(preg_replace_callback(1,2,3,4));
13+
} catch (\TypeError $e) {
14+
echo $e->getMessage() . \PHP_EOL;
15+
}
16+
817
$a = 5;
9-
var_dump(preg_replace_callback(1,2,3,4,$a));
18+
try {
19+
var_dump(preg_replace_callback(1,2,3,4,$a));
20+
} catch (\TypeError $e) {
21+
echo $e->getMessage() . \PHP_EOL;
22+
}
1023

11-
echo "Done\n";
1224
?>
13-
--EXPECTF--
14-
Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d
15-
string(1) "3"
16-
17-
Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d
18-
string(1) "3"
19-
20-
Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d
21-
string(1) "3"
22-
Done
25+
--EXPECT--
26+
preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given
27+
preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given
28+
preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given

0 commit comments

Comments
 (0)