Commit 2e564a747cc for php.net
commit 2e564a747ccd1836bb77e91a35a807e87765259c
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Sun Jun 28 18:41:05 2026 -0400
Fix GH-17387: crash on unterminated quote in phpdbg lexer
In the NORMAL condition a lone unterminated quote matched no rule, so
re2c backtracked to a zero-length GENERIC_ID accept. The rule body then
computed yyleng - unescape_string(yytext) as 0 - N, underflowing size_t
into a multi-gigabyte estrndup. Give a bare quote an explicit
one-character accept so the cursor advances and unescape_string is never
reached with a malformed token.
Fixes GH-17387
Closes GH-22506
diff --git a/NEWS b/NEWS
index 0f39334377e..531d6a334c0 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,9 @@ PHP NEWS
copying, ArrayAccess, stream lookup, directory iteration and extraction.
(Weilin Du)
+- PHPDBG:
+ . Fixed bug GH-17387 (Trivial crash in phpdbg lexer). (iliaal)
+
- Reflection:
. Fixed bug GH-22324 (Ignore leading namespace separator in
ReflectionParameter::__construct()). (jorgsowa)
diff --git a/sapi/phpdbg/phpdbg_lexer.l b/sapi/phpdbg/phpdbg_lexer.l
index ba1423c5a4e..7c6315fc2a0 100644
--- a/sapi/phpdbg/phpdbg_lexer.l
+++ b/sapi/phpdbg/phpdbg_lexer.l
@@ -166,6 +166,13 @@ INPUT ("\\"[#"']|["]("\\\\"|"\\"["]|[^\n\000"])*["]|[']("\\"[']|"\\\\"|[^\
return T_ID;
}
+<NORMAL>["'] {
+ phpdbg_init_param(yylval, STR_PARAM);
+ yylval->str = estrndup(yytext, yyleng);
+ yylval->len = yyleng;
+ return T_ID;
+}
+
<RAW>{INPUT} {
phpdbg_init_param(yylval, STR_PARAM);
yylval->str = estrdup(yytext);
diff --git a/sapi/phpdbg/tests/gh17387.phpt b/sapi/phpdbg/tests/gh17387.phpt
new file mode 100644
index 00000000000..af45fd4ba91
--- /dev/null
+++ b/sapi/phpdbg/tests/gh17387.phpt
@@ -0,0 +1,8 @@
+--TEST--
+GH-17387 (Trivial crash in phpdbg lexer)
+--PHPDBG--
+a';
+q
+--EXPECT--
+prompt> [The command "a" could not be found]
+prompt>