@@ -41,6 +41,7 @@ class WP_MySQL_Lexer {
41
41
*/
42
42
const WHITESPACE_MASK = " \t\n\r\f" ;
43
43
const DIGIT_MASK = '0123456789 ' ;
44
+ const HEX_DIGIT_MASK = '0123456789abcdefABCDEF ' ;
44
45
45
46
/**
46
47
* Tokens from the MySQL Workbench "predefined.tokens" list.
@@ -2480,8 +2481,6 @@ private function read_next_token(): int {
2480
2481
} elseif ( null !== $ byte && strspn ( $ byte , self ::WHITESPACE_MASK ) > 0 ) {
2481
2482
$ this ->bytes_already_read += strspn ( $ this ->sql , self ::WHITESPACE_MASK , $ this ->bytes_already_read );
2482
2483
$ type = self ::WHITESPACE ;
2483
- } elseif ( '0 ' === $ byte && ( 'x ' === $ next_byte || 'b ' === $ next_byte ) ) {
2484
- $ type = $ this ->read_number ();
2485
2484
} elseif ( ( 'x ' === $ byte || 'X ' === $ byte || 'b ' === $ byte || 'B ' === $ byte ) && "' " === $ next_byte ) {
2486
2485
$ type = $ this ->read_number ();
2487
2486
} elseif ( ( 'n ' === $ byte || 'N ' === $ byte ) && "' " === $ next_byte ) {
@@ -2597,25 +2596,35 @@ private function read_identifier(): int {
2597
2596
private function read_number (): int {
2598
2597
// @TODO: Support numeric-only identifier parts after "." (e.g., 1ea10.1).
2599
2598
2600
- $ byte = $ this ->sql [ $ this ->bytes_already_read ] ?? null ;
2601
- $ next_byte = $ this ->sql [ $ this ->bytes_already_read + 1 ] ?? null ;
2599
+ $ byte = $ this ->sql [ $ this ->bytes_already_read ] ?? null ;
2600
+ $ next_byte = $ this ->sql [ $ this ->bytes_already_read + 1 ] ?? null ;
2601
+ $ third_byte = $ this ->sql [ $ this ->bytes_already_read + 2 ] ?? null ;
2602
2602
2603
2603
if (
2604
2604
// HEX number in the form of 0xN.
2605
- ( '0 ' === $ byte && 'x ' === $ next_byte )
2605
+ (
2606
+ '0 ' === $ byte
2607
+ && 'x ' === $ next_byte
2608
+ && null !== $ third_byte
2609
+ && strspn ( $ third_byte , self ::HEX_DIGIT_MASK ) > 0
2610
+ )
2606
2611
// HEX number in the form of x'N' or X'N'.
2607
2612
|| ( ( 'x ' === $ byte || 'X ' === $ byte ) && "' " === $ next_byte )
2608
2613
) {
2609
2614
$ is_quoted = "' " === $ next_byte ;
2610
2615
$ this ->bytes_already_read += 2 ; // Consume "0x" or "x'".
2611
- $ this ->bytes_already_read += strspn ( $ this ->sql , ' 0123456789abcdefABCDEF ' , $ this ->bytes_already_read );
2616
+ $ this ->bytes_already_read += strspn ( $ this ->sql , self :: HEX_DIGIT_MASK , $ this ->bytes_already_read );
2612
2617
if ( $ is_quoted ) {
2613
2618
$ this ->bytes_already_read += 1 ; // Consume the "'".
2614
2619
}
2615
2620
$ type = self ::HEX_NUMBER ;
2616
2621
} elseif (
2617
2622
// BIN number in the form of 0bN.
2618
- ( '0 ' === $ byte && 'b ' === $ next_byte )
2623
+ (
2624
+ '0 ' === $ byte
2625
+ && 'b ' === $ next_byte
2626
+ && ( '0 ' === $ third_byte || '1 ' === $ third_byte )
2627
+ )
2619
2628
// BIN number in the form of b'N' or B'N'.
2620
2629
|| ( ( 'b ' === $ byte || 'B ' === $ byte ) && "' " === $ next_byte )
2621
2630
) {
0 commit comments