Skip to content

Commit 7d5869b

Browse files
committed
Use strspn to handle unquoted user-defined variables
1 parent 1e3e254 commit 7d5869b

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

wp-includes/mysql/class-wp-mysql-lexer.php

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,6 @@ class WP_MySQL_Lexer {
3939
*/
4040
const PATTERN_UNQUOTED_IDENTIFIER = '[a-zA-Z0-9_$\x{80}-\x{ffff}]*[a-zA-Z_$\x{80}-\x{ffff}][a-zA-Z0-9_$\x{80}-\x{ffff}]*';
4141

42-
/**
43-
* Unquoted user-defined variables:
44-
* https://dev.mysql.com/doc/refman/8.4/en/user-variables.html
45-
*
46-
* Rules:
47-
* 1. Starts with a '@'.
48-
* 2. Allowed following characters are ASCII a-z, A-Z, 0-9, ., $, _.
49-
*/
50-
const PATTER_UNQUOTED_USER_VARIABLE = '@[a-zA-Z0-9_$.]+';
51-
5242
/**
5343
* Tokens from the MySQL Workbench "predefined.tokens" list, including token numbers.
5444
* See:
@@ -2319,19 +2309,30 @@ private function next_token() {
23192309
$this->consume();
23202310
$this->type = self::CLOSE_CURLY_SYMBOL;
23212311
} elseif ( '@' === $la ) {
2312+
$this->consume(); // Consume the '@'.
2313+
23222314
if ( '@' === $la2 ) {
2323-
$this->consume(); // Consume the '@'.
2324-
$this->consume(); // Consume the '@'.
2315+
$this->consume(); // Consume the second '@'.
23252316
$this->type = self::AT_AT_SIGN_SYMBOL;
2326-
} elseif ( preg_match( '/\G' . self::PATTER_UNQUOTED_USER_VARIABLE . '/u', $this->input, $matches, 0, $this->position ) ) {
2327-
$this->text = $matches[0];
2328-
$this->position += strlen( $this->text );
2329-
$this->c = $this->input[ $this->position ] ?? null;
2330-
$this->n = $this->input[ $this->position + 1 ] ?? null;
2331-
$this->type = self::AT_TEXT_SUFFIX;
23322317
} else {
2333-
$this->consume();
2334-
$this->type = self::AT_SIGN_SYMBOL;
2318+
/**
2319+
* Check whether the '@' marks an unquoted user-defined variable:
2320+
* https://dev.mysql.com/doc/refman/8.4/en/user-variables.html
2321+
*
2322+
* Rules:
2323+
* 1. Starts with a '@'.
2324+
* 2. Allowed following characters are ASCII a-z, A-Z, 0-9, _, ., $.
2325+
*/
2326+
$length = strspn( $this->input, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$', $this->position );
2327+
if ( $length > 0 ) {
2328+
$this->text = substr( $this->input, $this->position, $length );
2329+
$this->position += $length;
2330+
$this->c = $this->input[ $this->position ] ?? null;
2331+
$this->n = $this->input[ $this->position + 1 ] ?? null;
2332+
$this->type = self::AT_TEXT_SUFFIX;
2333+
} else {
2334+
$this->type = self::AT_SIGN_SYMBOL;
2335+
}
23352336
}
23362337
} elseif ( '?' === $la ) {
23372338
$this->consume();
@@ -2574,13 +2575,13 @@ protected function quoted_text( string $quote ) {
25742575
}
25752576

25762577
// Unclosed string - unexpected EOF.
2577-
if ( $quote !== ( $this->input[ $pos ] ?? null ) ) {
2578+
if ( ( $this->input[ $pos ] ?? null ) !== $quote ) {
25782579
$this->type = self::INVALID_INPUT;
25792580
return;
25802581
}
25812582

25822583
// Check if the quote is doubled.
2583-
if ( $quote === ( $this->input[ $pos + 1 ] ?? null ) ) {
2584+
if ( ( $this->input[ $pos + 1 ] ?? null ) === $quote ) {
25842585
$pos += 2;
25852586
continue;
25862587
}

0 commit comments

Comments
 (0)