]> granicus.if.org Git - php/commitdiff
Use ZPP callable check for preg_replace_callback() $callback argument
authorGeorge Peter Banyard <girgias@php.net>
Mon, 22 Jun 2020 13:46:23 +0000 (15:46 +0200)
committerGeorge Peter Banyard <girgias@php.net>
Mon, 22 Jun 2020 13:56:36 +0000 (15:56 +0200)
ext/pcre/php_pcre.c
ext/pcre/php_pcre.stub.php
ext/pcre/php_pcre_arginfo.h
ext/pcre/tests/preg_replace_callback3.phpt

index 2ed5d9d7dd75ffc68c8eb3433ac6a8726dd711eb..98fa437bec707162335dd58f56eb1e7d61b5c85a 100644 (file)
@@ -2369,7 +2369,7 @@ PHP_FUNCTION(preg_replace)
    Perform Perl-style regular expression replacement using replacement callback. */
 PHP_FUNCTION(preg_replace_callback)
 {
-       zval *regex, *replace, *subject, *zcount = NULL;
+       zval *regex, *subject, *zcount = NULL;
        zend_long limit = -1, flags = 0;
        size_t replace_count;
        zend_fcall_info fci;
@@ -2378,7 +2378,7 @@ PHP_FUNCTION(preg_replace_callback)
        /* Get function parameters and do error-checking. */
        ZEND_PARSE_PARAMETERS_START(3, 6)
                Z_PARAM_ZVAL(regex)
-               Z_PARAM_ZVAL(replace)
+               Z_PARAM_FUNC(fci, fcc)
                Z_PARAM_ZVAL(subject)
                Z_PARAM_OPTIONAL
                Z_PARAM_LONG(limit)
@@ -2386,18 +2386,6 @@ PHP_FUNCTION(preg_replace_callback)
                Z_PARAM_LONG(flags)
        ZEND_PARSE_PARAMETERS_END();
 
-       if (!zend_is_callable_ex(replace, NULL, 0, NULL, &fcc, NULL)) {
-               zend_string     *callback_name = zend_get_callable_name(replace);
-               php_error_docref(NULL, E_WARNING, "Requires argument 2, '%s', to be a valid callback", ZSTR_VAL(callback_name));
-               zend_string_release_ex(callback_name, 0);
-               ZVAL_STR(return_value, zval_get_string(subject));
-               return;
-       }
-
-       fci.size = sizeof(fci);
-       fci.object = NULL;
-       ZVAL_COPY_VALUE(&fci.function_name, replace);
-
        replace_count = preg_replace_func_impl(return_value, regex, &fci, &fcc, subject, limit, flags);
        if (zcount) {
                ZEND_TRY_ASSIGN_REF_LONG(zcount, replace_count);
index af76b520f859b552407bfe4c846406e478bb4bb2..58bc5c378f29fee7d2a0aa046230f31eb9116bf2 100644 (file)
@@ -23,10 +23,8 @@ function preg_filter($regex, $replace, $subject, int $limit = -1, &$count = null
 /**
  * @param string|array $regex
  * @param string|array $subject
- *
- * TODO: $callback should be `callable`
  */
-function preg_replace_callback($regex, $callback, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
+function preg_replace_callback($regex, callable $callback, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
 
 /** @param string|array $subject */
 function preg_replace_callback_array(array $pattern, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {}
index 31fb0d9df7c5f0225513a033ced64f6b6ee441e8..52a48798c17d458c0e408bf5e2bbfb7dc5963184 100644 (file)
@@ -28,7 +28,7 @@ ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_replace_callback, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL)
        ZEND_ARG_INFO(0, regex)
-       ZEND_ARG_INFO(0, callback)
+       ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
        ZEND_ARG_INFO(0, subject)
        ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1")
        ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, count, "null")
index 842dfacb391a223be52e0dffd4e15bc8e929fcc0..9a26555cb5cbfb940c5de1d9ef8baf73b305f59a 100644 (file)
@@ -3,20 +3,26 @@ preg_replace_callback() 3
 --FILE--
 <?php
 
-var_dump(preg_replace_callback(1,2,3));
-var_dump(preg_replace_callback(1,2,3,4));
+try {
+    var_dump(preg_replace_callback(1,2,3));
+} catch (\TypeError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
+try {
+    var_dump(preg_replace_callback(1,2,3,4));
+} catch (\TypeError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
+
 $a = 5;
-var_dump(preg_replace_callback(1,2,3,4,$a));
+try {
+    var_dump(preg_replace_callback(1,2,3,4,$a));
+} catch (\TypeError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
 
-echo "Done\n";
 ?>
---EXPECTF--
-Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d
-string(1) "3"
-
-Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d
-string(1) "3"
-
-Warning: preg_replace_callback(): Requires argument 2, '2', to be a valid callback in %s on line %d
-string(1) "3"
-Done
+--EXPECT--
+preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given
+preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given
+preg_replace_callback(): Argument #2 ($callback) must be a valid callback, no array or string given