From 2c4971ce448baec6cac94c520c8112b81c4081bc Mon Sep 17 00:00:00 2001 From: dev-null-undefined Date: Wed, 21 Oct 2026 20:29:06 +0200 Subject: [PATCH] Fix GH-24490: pdo_pgsql prepare() hangs on a query containing a NUL byte No rule in the scanner matches a NUL byte, so what re2c does with one is undefined. Before 5ccc56b1e4 it happened to skip one character. Now it returns a zero-length text token and pdo_parse_params() loops forever, or reads an uninitialized YYMARKER if the NUL is the first byte. Add a default rule so a NUL is skipped as one character of text again. --- ext/pdo_pgsql/pgsql_sql_parser.re | 1 + ext/pdo_pgsql/tests/gh24490.phpt | 32 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 ext/pdo_pgsql/tests/gh24490.phpt diff --git a/ext/pdo_pgsql/pgsql_sql_parser.re b/ext/pdo_pgsql/pgsql_sql_parser.re index ce89c32f5357..5ecc6b1c01d1 100644 --- a/ext/pdo_pgsql/pgsql_sql_parser.re +++ b/ext/pdo_pgsql/pgsql_sql_parser.re @@ -48,5 +48,6 @@ int pdo_pgsql_scanner(pdo_scanner_t *s) COMMENTS { RET(PDO_PARSER_TEXT); } /* Plain text may contain e/E, as long as it doesn't end with one, which could start an E'...' string */ ([eE]* TEXTCHR)+ { RET(PDO_PARSER_TEXT); } + * { SKIP_ONE(PDO_PARSER_TEXT); } */ } diff --git a/ext/pdo_pgsql/tests/gh24490.phpt b/ext/pdo_pgsql/tests/gh24490.phpt new file mode 100644 index 000000000000..2cde8518ce2d --- /dev/null +++ b/ext/pdo_pgsql/tests/gh24490.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-24490 (pdo_pgsql: prepare() hangs on a query containing a NUL byte) +--EXTENSIONS-- +pdo_pgsql +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +foreach ([true, false] as $emulate) { + $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, $emulate); + $db->prepare("SELECT 'abc\0def'"); + $db->prepare("\0SELECT 1"); + try { + $db->prepare("SELECT '\0', ?, :p"); + } catch (\Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; + } +} +echo "Done\n"; +?> +--EXPECT-- +PDOException: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters +PDOException: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters +Done