Skip to content

Commit f8bd020

Browse files
committed
Fix out-of-bounds access in read_quoted_text()
The backslash-counting loop in read_quoted_text() ran before the EOF check. When strcspn() reached the end of the string without finding a closing quote, the loop accessed offsets past the string boundary: 1. strcspn() sets $at = strlen($sql) (no quote found). 2. Backslash check finds '\' at $at-1 (last byte), counts it ($i=1). 3. Odd count → treats absent quote as escaped, does $at += 1 (past end). 4. Next iteration: strcspn returns 0, $at stays past end. 5. Backslash check accesses $this->sql[strlen($sql)] → PHP warning. Fix: move the EOF check before the backslash-counting loop so unclosed strings are detected immediately. Also add a lower-bound guard to the backward walk to prevent underflow when a quote appears early in the string.
1 parent 040d5a6 commit f8bd020

1 file changed

Lines changed: 6 additions & 6 deletions

File tree

packages/mysql-on-sqlite/src/mysql/class-wp-mysql-lexer.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,6 +2842,11 @@ private function read_quoted_text(): ?int {
28422842
while ( true ) {
28432843
$at += strcspn( $this->sql, $quote, $at );
28442844

2845+
// Unclosed string - unexpected EOF.
2846+
if ( ( $this->sql[ $at ] ?? null ) !== $quote ) {
2847+
return null; // Invalid input.
2848+
}
2849+
28452850
/*
28462851
* By default, quotes can be escaped with a "\".
28472852
* When NO_BACKSLASH_ESCAPES SQL mode is active, the "\" treated as
@@ -2852,18 +2857,13 @@ private function read_quoted_text(): ?int {
28522857
* "\\\" is an escaped backslash and an escape sequence, and so on.
28532858
*/
28542859
if ( ! $no_backslash_escapes ) {
2855-
for ($i = 0; '\\' === $this->sql[ $at - $i - 1 ]; $i += 1);
2860+
for ( $i = 0; ( $at - $i - 1 ) >= 0 && '\\' === $this->sql[ $at - $i - 1 ]; $i += 1 );
28562861
if ( 1 === $i % 2 ) {
28572862
$at += 1;
28582863
continue;
28592864
}
28602865
}
28612866

2862-
// Unclosed string - unexpected EOF.
2863-
if ( ( $this->sql[ $at ] ?? null ) !== $quote ) {
2864-
return null; // Invalid input.
2865-
}
2866-
28672867
// Check if the quote is doubled.
28682868
if ( ( $this->sql[ $at + 1 ] ?? null ) === $quote ) {
28692869
$at += 2;

0 commit comments

Comments
 (0)