From: George Peter Banyard Date: Mon, 20 Jul 2020 23:52:50 +0000 (+0100) Subject: Use ZPP callable check in readline extension X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d9330fc67e1bad613a6d1d0bac3e9bcbc4c8fd27;p=php Use ZPP callable check in readline extension --- diff --git a/ext/readline/readline.c b/ext/readline/readline.c index 30eb8a3622..d569efe820 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -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); diff --git a/ext/readline/readline.stub.php b/ext/readline/readline.stub.php index a375ef444e..ecd81416eb 100644 --- a/ext/readline/readline.stub.php +++ b/ext/readline/readline.stub.php @@ -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 {} diff --git a/ext/readline/readline_arginfo.h b/ext/readline/readline_arginfo.h index 1b547aeefb..a83773b786 100644 --- a/ext/readline/readline_arginfo.h +++ b/ext/readline/readline_arginfo.h @@ -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 diff --git a/ext/readline/tests/readline_callback_handler_install_001.phpt b/ext/readline/tests/readline_callback_handler_install_001.phpt index 7f908ee393..218f8ee11e 100644 --- a/ext/readline/tests/readline_callback_handler_install_001.phpt +++ b/ext/readline/tests/readline_callback_handler_install_001.phpt @@ -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 diff --git a/ext/readline/tests/readline_completion_function_001.phpt b/ext/readline/tests/readline_completion_function_001.phpt index 6ba88756b8..2556027bff 100644 --- a/ext/readline/tests/readline_completion_function_001.phpt +++ b/ext/readline/tests/readline_completion_function_001.phpt @@ -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