Skip to content

Commit d9330fc

Browse files
committed
Use ZPP callable check in readline extension
1 parent a109767 commit d9330fc

File tree

5 files changed

+31
-42
lines changed

5 files changed

+31
-42
lines changed

ext/readline/readline.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -469,21 +469,15 @@ static char **_readline_completion_cb(const char *text, int start, int end)
469469

470470
PHP_FUNCTION(readline_completion_function)
471471
{
472-
zval *arg;
472+
zend_fcall_info fci;
473+
zend_fcall_info_cache fcc;
473474

474-
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg)) {
475+
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "f", &fci, &fcc)) {
475476
RETURN_THROWS();
476477
}
477478

478-
if (!zend_is_callable(arg, 0, NULL)) {
479-
zend_string *name = zend_get_callable_name(arg);
480-
php_error_docref(NULL, E_WARNING, "%s is not callable", ZSTR_VAL(name));
481-
zend_string_release_ex(name, 0);
482-
RETURN_FALSE;
483-
}
484-
485479
zval_ptr_dtor(&_readline_completion);
486-
ZVAL_COPY(&_readline_completion, arg);
480+
ZVAL_COPY(&_readline_completion, &fci.function_name);
487481

488482
rl_attempted_completion_function = _readline_completion_cb;
489483
if (rl_attempted_completion_function == NULL) {
@@ -514,27 +508,21 @@ static void php_rl_callback_handler(char *the_line)
514508
/* {{{ Initializes the readline callback interface and terminal, prints the prompt and returns immediately */
515509
PHP_FUNCTION(readline_callback_handler_install)
516510
{
517-
zval *callback;
518511
char *prompt;
512+
zend_fcall_info fci;
513+
zend_fcall_info_cache fcc;
519514
size_t prompt_len;
520515

521-
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &prompt, &prompt_len, &callback)) {
516+
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &prompt, &prompt_len, &fci, &fcc)) {
522517
RETURN_THROWS();
523518
}
524519

525-
if (!zend_is_callable(callback, 0, NULL)) {
526-
zend_string *name = zend_get_callable_name(callback);
527-
php_error_docref(NULL, E_WARNING, "%s is not callable", ZSTR_VAL(name));
528-
zend_string_release_ex(name, 0);
529-
RETURN_FALSE;
530-
}
531-
532520
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
533521
rl_callback_handler_remove();
534522
zval_ptr_dtor(&_prepped_callback);
535523
}
536524

537-
ZVAL_COPY(&_prepped_callback, callback);
525+
ZVAL_COPY(&_prepped_callback, &fci.function_name);
538526

539527
rl_callback_handler_install(prompt, php_rl_callback_handler);
540528

ext/readline/readline.stub.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,11 @@ function readline_read_history(?string $filename = null): bool {}
2222

2323
function readline_write_history(?string $filename = null): bool {}
2424

25-
/**
26-
* @param callable $funcname
27-
*/
28-
function readline_completion_function($funcname): bool {}
25+
function readline_completion_function(callable $funcname): bool {}
2926

3027

3128
#if HAVE_RL_CALLBACK_READ_CHAR
32-
/**
33-
* @param callable $callback
34-
*/
35-
function readline_callback_handler_install(string $prompt, $callback): bool {}
29+
function readline_callback_handler_install(string $prompt, callable $callback): bool {}
3630

3731
function readline_callback_read_char(): void {}
3832

ext/readline/readline_arginfo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 00f57c17d30b8071c9e3e231f5c9e0376799ed48 */
2+
* Stub hash: c7d13f6960171cab30984837379db25b32f38c36 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_readline, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, prompt, IS_STRING, 1, "null")
@@ -29,13 +29,13 @@ ZEND_END_ARG_INFO()
2929
#define arginfo_readline_write_history arginfo_readline_read_history
3030

3131
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_readline_completion_function, 0, 1, _IS_BOOL, 0)
32-
ZEND_ARG_INFO(0, funcname)
32+
ZEND_ARG_TYPE_INFO(0, funcname, IS_CALLABLE, 0)
3333
ZEND_END_ARG_INFO()
3434

3535
#if HAVE_RL_CALLBACK_READ_CHAR
3636
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_readline_callback_handler_install, 0, 2, _IS_BOOL, 0)
3737
ZEND_ARG_TYPE_INFO(0, prompt, IS_STRING, 0)
38-
ZEND_ARG_INFO(0, callback)
38+
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
3939
ZEND_END_ARG_INFO()
4040
#endif
4141

ext/readline/tests/readline_callback_handler_install_001.phpt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ function foo() {
1212
}
1313

1414
var_dump(readline_callback_handler_install('testing: ', 'foo'));
15-
var_dump(readline_callback_handler_install('testing: ', 'foobar!'));
15+
try {
16+
var_dump(readline_callback_handler_install('testing: ', 'foobar!'));
17+
} catch (\TypeError $e) {
18+
echo $e->getMessage() . \PHP_EOL;
19+
}
1620

1721
?>
18-
--EXPECTF--
19-
%Atesting: bool(true)
20-
21-
Warning: readline_callback_handler_install(): foobar! is not callable in %s on line %d
22-
bool(false)
22+
--EXPECT--
23+
testing: bool(true)
24+
readline_callback_handler_install(): Argument #2 ($callback) must be a valid callback, function "foobar!" not found or invalid function name

ext/readline/tests/readline_completion_function_001.phpt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ $data = array(
1515
);
1616

1717
foreach ($data as $callback) {
18-
readline_completion_function($callback);
18+
try {
19+
var_dump(readline_completion_function($callback));
20+
} catch (\TypeError $e) {
21+
echo $e->getMessage() . \PHP_EOL;
22+
}
1923
}
2024

2125
?>
22-
--EXPECTF--
23-
Warning: readline_completion_function(): 1 is not callable in %s on line %d
24-
25-
Warning: readline_completion_function(): 1.1231 is not callable in %s on line %d
26+
--EXPECT--
27+
bool(true)
28+
bool(true)
29+
readline_completion_function(): Argument #1 ($funcname) must be a valid callback, no array or string given
30+
readline_completion_function(): Argument #1 ($funcname) must be a valid callback, no array or string given

0 commit comments

Comments
 (0)