[php-src] master: Merge branch 'PHP-8.4' into PHP-8.5

Weilin Du <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Weilin Du (LamentXU123)
Date: 2026-08-12T22:25:35+08:00

Commit: https://github.com/php/php-src/commit/b0ae3d5c84fe47cad6cd70df6a71ebd491b88306
Raw diff: https://github.com/php/php-src/commit/b0ae3d5c84fe47cad6cd70df6a71ebd491b88306.diff

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  ext/readline: Fix class constant completion in readline interactive shell (#23218)

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 ab010e5a0ec7..72c4bb81866f 100644
--- a/NEWS
+++ b/NEWS
@@ -81,6 +81,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 fb8f9a261637..985a797754d9 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.