Files
php-src/ext/pdo_pgsql/pgsql_sql_parser.re
dev-null-undefined b91ea8889c 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
2026-10-22 14:26:24 +01:00

54 lines
2.1 KiB
ReasonML

/*
+----------------------------------------------------------------------+
| Copyright © The PHP Group and Contributors. |
+----------------------------------------------------------------------+
| This source file is subject to the Modified BSD License that is |
| bundled with this package in the file LICENSE, and is available |
| through the World Wide Web at <https://www.php.net/license/>. |
| |
| SPDX-License-Identifier: BSD-3-Clause |
+----------------------------------------------------------------------+
| Author: Matteo Beccati <mbeccati@php.net> |
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "ext/pdo/php_pdo_driver.h"
#include "ext/pdo/pdo_sql_parser.h"
int pdo_pgsql_scanner(pdo_scanner_t *s)
{
const char *cursor = s->cur;
s->tok = cursor;
/*!re2c
BINDCHR = [:][a-zA-Z0-9_]+;
QUESTION = [?];
ESCQUESTION = [?][?];
COMMENTS = ("/*"([^*]+|[*]+[^/*])*[*]*"*/"|"--".*);
DOLQ_START = [A-Za-z\200-\377_];
DOLQ_CONT = [A-Za-z\200-\377_0-9];
SPECIALS = [$eE:?"'/-];
MULTICHAR = [:]{2,};
ANYNOEOF = [\001-\377];
TEXTCHR = ANYNOEOF\SPECIALS;
*/
/*!re2c
[eE](['](([']['])|([\\]ANYNOEOF)|ANYNOEOF\['\\])*[']) { RET(PDO_PARSER_TEXT); }
(["]((["]["])|ANYNOEOF\["])*["]) { RET(PDO_PARSER_TEXT); }
(['](([']['])|ANYNOEOF\['])*[']) { RET(PDO_PARSER_TEXT); }
[$](DOLQ_START DOLQ_CONT*)?[$] { RET(PDO_PARSER_CUSTOM_QUOTE); }
MULTICHAR { RET(PDO_PARSER_TEXT); }
ESCQUESTION { RET(PDO_PARSER_ESCAPED_QUESTION); }
BINDCHR { RET(PDO_PARSER_BIND); }
QUESTION { RET(PDO_PARSER_BIND_POS); }
SPECIALS { SKIP_ONE(PDO_PARSER_TEXT); }
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); }
*/
}