Skip to content
This repository was archived by the owner on Jun 2, 2025. It is now read-only.

Commit 489deb8

Browse files
committed
Explicitly support only ASCII identifiers
1 parent 5ed53f0 commit 489deb8

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5139,4 +5139,29 @@ public function testColumnNamesAreNotCaseSensitive(): void {
51395139
$this->assertCount( 1, $result );
51405140
$this->assertSame( 'value', $result[0]->Field );
51415141
}
5142+
5143+
public function testAliasesMustBeAscii(): void {
5144+
$this->expectException( WP_SQLite_Driver_Exception::class );
5145+
$this->expectExceptionMessage( 'The SQLite driver only supports ASCII characters in identifiers.' );
5146+
$this->assertQuery( 'SELECT 123 AS `ńôñ-ášçíì`' );
5147+
}
5148+
5149+
public function testTableNamesMustBeAscii(): void {
5150+
$this->expectException( WP_SQLite_Driver_Exception::class );
5151+
$this->expectExceptionMessage( 'The SQLite driver only supports ASCII characters in identifiers.' );
5152+
$this->assertQuery( 'CREATE TABLE `ńôñ-ášçíì` (id INT)' );
5153+
}
5154+
5155+
public function testColumnNamesMustBeAscii(): void {
5156+
$this->expectException( WP_SQLite_Driver_Exception::class );
5157+
$this->expectExceptionMessage( 'The SQLite driver only supports ASCII characters in identifiers.' );
5158+
$this->assertQuery( 'CREATE TABLE t (`ńôñ-ášçíì` INT)' );
5159+
}
5160+
5161+
public function testIndexNamesMustBeAscii(): void {
5162+
$this->expectException( WP_SQLite_Driver_Exception::class );
5163+
$this->expectExceptionMessage( 'The SQLite driver only supports ASCII characters in identifiers.' );
5164+
$this->assertQuery( 'CREATE TABLE t (id INT)' );
5165+
$this->assertQuery( 'CREATE INDEX `ńôñ-ášçíì` ON t (id)' );
5166+
}
51425167
}

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2121,7 +2121,21 @@ private function translate( $node ): ?string {
21212121
case 'identifierKeyword':
21222122
return '`' . $this->translate( $node->get_first_child() ) . '`';
21232123
case 'pureIdentifier':
2124-
return $this->translate_pure_identifier( $node );
2124+
$value = $this->translate_pure_identifier( $node );
2125+
2126+
/*
2127+
* At the moment, we only support ASCII bytes in all identifiers.
2128+
* This is because SQLite doesn't support case-insensitive Unicode
2129+
* character matching: https://sqlite.org/faq.html#q18
2130+
*/
2131+
for ( $i = 0; $i < strlen( $value ); $i++ ) {
2132+
if ( ord( $value[ $i ] ) > 127 ) {
2133+
throw $this->new_driver_exception(
2134+
'The SQLite driver only supports ASCII characters in identifiers.'
2135+
);
2136+
}
2137+
}
2138+
return $value;
21252139
case 'textStringLiteral':
21262140
return $this->translate_string_literal( $node );
21272141
case 'dataType':

wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,6 +2113,19 @@ private function get_value( WP_Parser_Node $node ): string {
21132113
foreach ( $node->get_children() as $child ) {
21142114
if ( $child instanceof WP_Parser_Node ) {
21152115
$value = $this->get_value( $child );
2116+
2117+
/*
2118+
* At the moment, we only support ASCII bytes in all identifiers.
2119+
* This is because SQLite doesn't support case-insensitive Unicode
2120+
* character matching: https://sqlite.org/faq.html#q18
2121+
*/
2122+
if ( 'pureIdentifier' === $child->rule_name ) {
2123+
for ( $i = 0; $i < strlen( $value ); $i++ ) {
2124+
if ( ord( $value[ $i ] ) > 127 ) {
2125+
throw new Exception( 'The SQLite driver only supports ASCII characters in identifiers.' );
2126+
}
2127+
}
2128+
}
21162129
} else {
21172130
$value = $child->get_value();
21182131
}

0 commit comments

Comments
 (0)