]> granicus.if.org Git - php/commitdiff
Use ZPP callable check in readline extension
authorGeorge Peter Banyard <girgias@php.net>
Mon, 20 Jul 2020 23:52:50 +0000 (00:52 +0100)
committerGeorge Peter Banyard <girgias@php.net>
Mon, 20 Jul 2020 23:52:50 +0000 (00:52 +0100)
ext/readline/readline.c
ext/readline/readline.stub.php
ext/readline/readline_arginfo.h
ext/readline/tests/readline_callback_handler_install_001.phpt
ext/readline/tests/readline_completion_function_001.phpt

index 30eb8a362244a215a7038f0bfbe527816f3f8733..d569efe820cadbb05cc8188d10420e3488b27f2d 100644 (file)
@@ -469,21 +469,15 @@ static char **_readline_completion_cb(const char *text, int start, int end)
 
 PHP_FUNCTION(readline_completion_function)
 {
-       zval *arg;
+       zend_fcall_info fci;
+       zend_fcall_info_cache fcc;
 
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg)) {
+       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "f", &fci, &fcc)) {
                RETURN_THROWS();
        }
 
-       if (!zend_is_callable(arg, 0, NULL)) {
-               zend_string *name = zend_get_callable_name(arg);
-               php_error_docref(NULL, E_WARNING, "%s is not callable", ZSTR_VAL(name));
-               zend_string_release_ex(name, 0);
-               RETURN_FALSE;
-       }
-
        zval_ptr_dtor(&_readline_completion);
-       ZVAL_COPY(&_readline_completion, arg);
+       ZVAL_COPY(&_readline_completion, &fci.function_name);
 
        rl_attempted_completion_function = _readline_completion_cb;
        if (rl_attempted_completion_function == NULL) {
@@ -514,27 +508,21 @@ static void php_rl_callback_handler(char *the_line)
 /* {{{ Initializes the readline callback interface and terminal, prints the prompt and returns immediately */
 PHP_FUNCTION(readline_callback_handler_install)
 {
-       zval *callback;
        char *prompt;
+       zend_fcall_info fci;
+       zend_fcall_info_cache fcc;
        size_t prompt_len;
 
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &prompt, &prompt_len, &callback)) {
+       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &prompt, &prompt_len, &fci, &fcc)) {
                RETURN_THROWS();
        }
 
-       if (!zend_is_callable(callback, 0, NULL)) {
-               zend_string *name = zend_get_callable_name(callback);
-               php_error_docref(NULL, E_WARNING, "%s is not callable", ZSTR_VAL(name));
-               zend_string_release_ex(name, 0);
-               RETURN_FALSE;
-       }
-
        if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
                rl_callback_handler_remove();
                zval_ptr_dtor(&_prepped_callback);
        }
 
-       ZVAL_COPY(&_prepped_callback, callback);
+       ZVAL_COPY(&_prepped_callback, &fci.function_name);
 
        rl_callback_handler_install(prompt, php_rl_callback_handler);
 
index a375ef444e8589cd3a29cd1f9004beea54bd3ece..ecd81416eba809a18c01562082934f3204cc72ae 100644 (file)
@@ -22,17 +22,11 @@ function readline_read_history(?string $filename = null): bool {}
 
 function readline_write_history(?string $filename = null): bool {}
 
-/**
- * @param callable $funcname
- */
-function readline_completion_function($funcname): bool {}
+function readline_completion_function(callable $funcname): bool {}
 
 
 #if HAVE_RL_CALLBACK_READ_CHAR
-/**
- * @param callable $callback
- */
-function readline_callback_handler_install(string $prompt, $callback): bool {}
+function readline_callback_handler_install(string $prompt, callable $callback): bool {}
 
 function readline_callback_read_char(): void {}
 
index 1b547aeefb9ca10f78d025f4f087d53e73eef4de..a83773b786cdf76354554612fd7ad5454654075b 100644 (file)
@@ -1,5 +1,5 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 00f57c17d30b8071c9e3e231f5c9e0376799ed48 */
+ * Stub hash: c7d13f6960171cab30984837379db25b32f38c36 */
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_readline, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
        ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, prompt, IS_STRING, 1, "null")
@@ -29,13 +29,13 @@ ZEND_END_ARG_INFO()
 #define arginfo_readline_write_history arginfo_readline_read_history
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_readline_completion_function, 0, 1, _IS_BOOL, 0)
-       ZEND_ARG_INFO(0, funcname)
+       ZEND_ARG_TYPE_INFO(0, funcname, IS_CALLABLE, 0)
 ZEND_END_ARG_INFO()
 
 #if HAVE_RL_CALLBACK_READ_CHAR
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_readline_callback_handler_install, 0, 2, _IS_BOOL, 0)
        ZEND_ARG_TYPE_INFO(0, prompt, IS_STRING, 0)
-       ZEND_ARG_INFO(0, callback)
+       ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
 ZEND_END_ARG_INFO()
 #endif
 
index 7f908ee3933271efa6363df463acb83c706e1d49..218f8ee11e0b622558eeffc12d42d53dcb9c2f85 100644 (file)
@@ -12,11 +12,13 @@ function foo() {
 }
 
 var_dump(readline_callback_handler_install('testing: ', 'foo'));
-var_dump(readline_callback_handler_install('testing: ', 'foobar!'));
+try {
+    var_dump(readline_callback_handler_install('testing: ', 'foobar!'));
+} catch (\TypeError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
 
 ?>
---EXPECTF--
-%Atesting: bool(true)
-
-Warning: readline_callback_handler_install(): foobar! is not callable in %s on line %d
-bool(false)
+--EXPECT--
+testing: bool(true)
+readline_callback_handler_install(): Argument #2 ($callback) must be a valid callback, function "foobar!" not found or invalid function name
index 6ba88756b8bba21e153d0714808cedefc605457a..2556027bff37e42da9d9eb5c8da83c04c1b8db87 100644 (file)
@@ -15,11 +15,16 @@ $data = array(
 );
 
 foreach ($data as $callback) {
-    readline_completion_function($callback);
+    try {
+        var_dump(readline_completion_function($callback));
+    } catch (\TypeError $e) {
+        echo $e->getMessage() . \PHP_EOL;
+    }
 }
 
 ?>
---EXPECTF--
-Warning: readline_completion_function(): 1 is not callable in %s on line %d
-
-Warning: readline_completion_function(): 1.1231 is not callable in %s on line %d
+--EXPECT--
+bool(true)
+bool(true)
+readline_completion_function(): Argument #1 ($funcname) must be a valid callback, no array or string given
+readline_completion_function(): Argument #1 ($funcname) must be a valid callback, no array or string given