[php-src] master: Fix GH-24490: pdo_pgsql prepare() hangs on a query containing a NUL byte

From: Date: Thu, 22 Oct 2026 13:28:35 +0000
Subject: [php-src] master: Fix GH-24490: pdo_pgsql prepare() hangs on a query containing a NUL byte
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142575@lists.php.net to get a copy of this message
Author: dev-null-undefined (dev-null-undefined) Committer: David Carlier (devnexen) Date: 2026-10-22T14:26:24+01:00 Commit: https://github.com/php/php-src/commit/b91ea8889cb4e802a0764ecf7168118fcc765d40 Raw diff: https://github.com/php/php-src/commit/b91ea8889cb4e802a0764ecf7168118fcc765d40.diff 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. Close GH-24496 Changed paths: A ext/pdo_pgsql/tests/gh24490.phpt M NEWS M ext/pdo_pgsql/pgsql_sql_parser.re Diff: diff --git a/NEWS b/NEWS index 5155d8ede346..6bb8496271f8 100644 --- a/NEWS +++ b/NEWS @@ -92,6 +92,8 @@ PHP NEWS . Improved performance of the SQL parser that handles placeholders. (brainexe) . Improved performance of fetching integer columns. (brainexe) + . Fixed bug GH-24490 (pdo_pgsql prepare() hangs on a query containing a NUL + byte). (dev-null-undefined) - PGSQL: . Fixed pg_lo_write() rejecting data containing null bytes. (Ilia Alshanetsky) 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-- +<?php +require __DIR__ . '/config.inc'; +require dirname(__DIR__, 2) . '/pdo/tests/pdo_test.inc'; +PDOTest::skip(); +?> +--FILE-- +<?php +require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; +$db = PDOTest::test_factory(__DIR__ . '/common.phpt'); +$db->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

« previous php.cvs (#142575) next »