@@ -1808,16 +1808,34 @@ private function translate_string_literal( WP_Parser_Node $node ): string {
1808
1808
}
1809
1809
1810
1810
/*
1811
- * 6. Remove null characters.
1811
+ * 6. Handle null characters.
1812
1812
*
1813
- * SQLite doesn't support null characters in strings.
1814
- */
1815
- $ value = str_replace ( "\0" , '' , $ value );
1816
-
1817
- /*
1818
- * 7. Escape and add quotes.
1813
+ * SQLite doesn't fully support null characters (\u0000) in strings.
1814
+ * However, it can store them and read them, with some limitations.
1815
+ *
1816
+ * In PHP, null bytes are often produced by the serialize() function.
1817
+ * Removing them would damage the serialized data.
1818
+ *
1819
+ * There is no way to store null bytes using a string literal, so we
1820
+ * need to split the string and concatenate null bytes with its parts.
1821
+ * This will convert literals will null bytes to expressions.
1822
+ *
1823
+ * Alternatively, we could replace string literals with parameters and
1824
+ * pass them using prepared statements. However, that's not universally
1825
+ * applicable for all string literals (e.g., in default column values).
1826
+ *
1827
+ * See:
1828
+ * https://www.sqlite.org/nulinstr.html
1819
1829
*/
1820
- return "' " . str_replace ( "' " , "'' " , $ value ) . "' " ;
1830
+ $ parts = array ();
1831
+ foreach ( explode ( "\0" , $ value ) as $ segment ) {
1832
+ // Escape and quote each segment.
1833
+ $ parts [] = "' " . str_replace ( "' " , "'' " , $ segment ) . "' " ;
1834
+ }
1835
+ if ( count ( $ parts ) > 1 ) {
1836
+ return '( ' . implode ( ' || CHAR(0) || ' , $ parts ) . ') ' ;
1837
+ }
1838
+ return $ parts [0 ];
1821
1839
}
1822
1840
1823
1841
private function translate_pure_identifier ( WP_Parser_Node $ node ): string {
0 commit comments