[php-src] PHP-8.4: ext/readline: Fix class constant completion in readline interactive shell (#23218)
Weilin Du via GitHub <[email protected]>
| Newsgroups | gmane.comp.php.cvs.general |
|---|---|
| Message-ID | <[email protected]> |
Author: Weilin Du (LamentXU123) Committer: GitHub (web-flow) Pusher: LamentXU123 Date: 2026-08-12T22:04:57+08:00 Commit: https://github.com/php/php-src/commit/f6dba91e6219ecb77018569f9800eca6edebb57f Raw diff: https://github.com/php/php-src/commit/f6dba91e6219ecb77018569f9800eca6edebb57f.diff ext/readline: Fix class constant completion in readline interactive shell (#23218) Reference: https://github.com/php/php-src/pull/22994#discussion_r3708633591_ php -a class constant completion passed the full ClassName::PREFIX string to the constant completion generator. And textlen had already been shortened to the part after "::". This commit fixes this bug. Co-authored-by: Ilia Alshanetsky <[email protected]> Changed paths: A ext/readline/tests/readline_cli_completion_class_constant.phpt M NEWS M ext/readline/readline_cli.c Diff: diff --git a/NEWS b/NEWS index ffefe0d338ec..0d9e42792078 100644 --- a/NEWS +++ b/NEWS @@ -60,6 +60,9 @@ PHP NEWS . Fixed segfault in ReflectionMethod::createFromMethodName() on an uninstantiable subclass. (iliaal) +- Readline: + . Fixed class constant completion in the interactive shell. (Weilin Du) + - Session: . Fix corruption in mod_mm. (ndossche) . Fixed bug GH-23043 (broken session id code can cause zend_mm_heap diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c index ca4e8eb4fe9f..ff5caee9eb7d 100644 --- a/ext/readline/readline_cli.c +++ b/ext/readline/readline_cli.c @@ -531,6 +531,7 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */ } else { char *lc_text; const char *class_name_end; + const char *constant_text = text; zend_string *class_name = NULL; zend_class_entry *ce = NULL; @@ -543,6 +544,7 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */ zend_string_release_ex(class_name, 0); return NULL; } + constant_text = class_name_end + 2; lc_text = zend_str_tolower_dup(class_name_end + 2, textlen - 2 - class_name_len); textlen -= (class_name_len + 2); } else { @@ -559,7 +561,7 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */ ZEND_FALLTHROUGH; case 2: case 3: - retval = cli_completion_generator_define(text, textlen, &cli_completion_state, ce ? &ce->constants_table : EG(zend_constants)); + retval = cli_completion_generator_define(constant_text, textlen, &cli_completion_state, ce ? &ce->constants_table : EG(zend_constants)); if (retval || ce) { break; } diff --git a/ext/readline/tests/readline_cli_completion_class_constant.phpt b/ext/readline/tests/readline_cli_completion_class_constant.phpt new file mode 100644 index 000000000000..1d4e6228df01 --- /dev/null +++ b/ext/readline/tests/readline_cli_completion_class_constant.phpt @@ -0,0 +1,30 @@ +--TEST-- +Interactive shell: class constant completion +--EXTENSIONS-- +readline +--SKIPIF-- +<?php +if (READLINE_LIB !== "readline") die('skip readline only'); +if (!function_exists('shell_exec')) die('skip shell_exec() not available'); +?> +--FILE-- +<?php +$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); +$ini = getenv('TEST_PHP_EXTRA_ARGS'); + +putenv('TERM=VT100'); +putenv('INPUTRC=/dev/null'); + +$code = <<<'PHP' +class Foo { + public const FooBar = "wrong_constant\n"; + public const Zed = "zed_ok\n"; +} +echo strtoupper(Foo::Ze ); +exit +PHP; + +echo shell_exec("echo " . escapeshellarg($code) . " | $php $ini -a"); +?> +--EXPECTF-- +%AInteractive shell%AZED_OK%A