Commit c2c01aea6c4 for php.net
commit c2c01aea6c4ef9bf6fee6b8e460ac749e72f105f
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Fri Aug 21 14:11:26 2026 -0400
Fix heap over-read in cli_get_prompt() for empty cli.prompt
The prompt parser ran as a do-while, so an empty cli.prompt executed
the body on the terminator and scanned past it. Use a while loop and
smart_str_extract(), which returns the interned empty string when
nothing was appended. No regression test: extra unicode warnings from
the over-read depend on heap contents, so a .phpt cannot pin the bug
red-before.
Closes GH-23415
diff --git a/NEWS b/NEWS
index 0382330fa8c..d81d3170a6f 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,10 @@ PHP NEWS
. Fixed PDOStatement::getColumnMeta() reading out of bounds for an invalid
column index. (Ilia Alshanetsky)
+- Readline:
+ . Fixed a heap over-read in the interactive shell prompt when cli.prompt is
+ set to an empty string. (Ilia Alshanetsky)
+
- Sockets:
. Fixed socket_select() silently truncating sets larger than FD_SETSIZE on
Windows. (David Carlier)
diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c
index ff5caee9eb7..8319b3b4364 100644
--- a/ext/readline/readline_cli.c
+++ b/ext/readline/readline_cli.c
@@ -130,7 +130,7 @@ static zend_string *cli_get_prompt(char *block, char prompt) /* {{{ */
char *prompt_spec = CLIR_G(prompt) ? CLIR_G(prompt) : DEFAULT_PROMPT;
bool unicode_warned = false;
- do {
+ while (*prompt_spec) {
if (*prompt_spec == '\\') {
switch (prompt_spec[1]) {
case '\\':
@@ -198,9 +198,9 @@ static zend_string *cli_get_prompt(char *block, char prompt) /* {{{ */
smart_str_appendc(&retval, '?');
}
}
- } while (++prompt_spec && *prompt_spec);
- smart_str_0(&retval);
- return retval.s;
+ ++prompt_spec;
+ }
+ return smart_str_extract(&retval);
}
/* }}} */