@@ -4932,4 +4932,53 @@ public function testNoBackslashEscapesSqlModeWithPatternMatching(): void {
4932
4932
$ result = $ this ->assertQuery ( "SELECT value FROM t WHERE value LIKE 'abc {$ backslash }{$ backslash }x' " );
4933
4933
$ this ->assertCount ( 0 , $ result );
4934
4934
}
4935
+
4936
+ public function testQuoteMysqlUtf8StringLiteral (): void {
4937
+ // WP_SQLite_Driver::quote_mysql_utf8_string_literal() is a private method.
4938
+ // Let's use a closure bound to the driver instance to access it for tests.
4939
+ $ quote = Closure::bind (
4940
+ function ( string $ utf8_literal ) {
4941
+ return $ this ->quote_mysql_utf8_string_literal ( $ utf8_literal );
4942
+ },
4943
+ $ this ->engine ,
4944
+ WP_SQLite_Driver::class
4945
+ );
4946
+
4947
+ $ backslash = chr ( 92 );
4948
+
4949
+ // The formatted string must be enclosed in single quotes.
4950
+ $ this ->assertSame ( "'abc' " , $ quote ( 'abc ' ) );
4951
+
4952
+ // Single quotes must be escaped by being doubled.
4953
+ $ this ->assertSame ( "'''' " , $ quote ( chr ( 39 ) ) );
4954
+ $ this ->assertSame ( "'abc''xyz' " , $ quote ( "abc'xyz " ) );
4955
+
4956
+ // Backslashes must be escaped by being doubled.
4957
+ $ this ->assertSame ( "' {$ backslash }{$ backslash }' " , $ quote ( $ backslash ) );
4958
+ $ this ->assertSame ( "'abc {$ backslash }{$ backslash }xyz' " , $ quote ( "abc {$ backslash }xyz " ) );
4959
+
4960
+ // ASCII NULL, newline, and carriage return must be escaped with a backslash.
4961
+ $ this ->assertSame ( "' {$ backslash }0' " , $ quote ( chr ( 0 ) ) ); // ASCII NULL (\0)
4962
+ $ this ->assertSame ( "' {$ backslash }n' " , $ quote ( chr ( 10 ) ) ); // newline (\n)
4963
+ $ this ->assertSame ( "' {$ backslash }r' " , $ quote ( chr ( 13 ) ) ); // carriage return (\r)
4964
+
4965
+ // Other valid UTF-8 characters must be preserved.
4966
+ $ this ->assertSame ( "' " . chr ( 34 ) . "' " , $ quote ( chr ( 34 ) ) ); // double quote
4967
+ $ this ->assertSame ( "' " . chr ( 96 ) . "' " , $ quote ( chr ( 96 ) ) ); // backtick
4968
+ $ this ->assertSame ( "' " . chr ( 8 ) . "' " , $ quote ( chr ( 8 ) ) ); // backspace
4969
+ $ this ->assertSame ( "' " . chr ( 9 ) . "' " , $ quote ( chr ( 9 ) ) ); // tab
4970
+ $ this ->assertSame ( "' " . chr ( 26 ) . "' " , $ quote ( chr ( 26 ) ) ); // Control+Z
4971
+ $ this ->assertSame ( "'🙂' " , $ quote ( '🙂 ' ) );
4972
+ $ this ->assertSame ( "'👪' " , $ quote ( '👪 ' ) );
4973
+ $ this ->assertSame ( "'Ʈềʂᴛӏń𝒈 𝙨𝑜ɱê Ū𝐓Ϝ-8 𝒄𝒽ȃᵲ𝛼çṱ𝘦ᴦ𐑈.' " , $ quote ( 'Ʈềʂᴛӏń𝒈 𝙨𝑜ɱê Ū𝐓Ϝ-8 𝒄𝒽ȃᵲ𝛼çṱ𝘦ᴦ𐑈. ' ) );
4974
+
4975
+ // Invalid UTF-8 sequences may fail to be preserved.
4976
+ // The following 2-byte sequence with a single quote as the last byte
4977
+ // is not a valid UTF-8 sequence. The single quote gets escaped.
4978
+ // At the moment, this is the intended behavior.
4979
+ $ this ->assertSame (
4980
+ "' " . chr ( 0xC0 ) . chr ( 39 ) . chr ( 39 ) . "' " ,
4981
+ $ quote ( chr ( 0xC0 ) . chr ( 39 ) )
4982
+ );
4983
+ }
4935
4984
}
0 commit comments