@@ -1417,7 +1417,7 @@ private function execute_delete() {
14171417 // SELECT to fetch the IDs of the rows to delete, then delete them
14181418 // using a separate DELETE query.
14191419
1420- $ this ->table_name = $ rewriter ->skip ()->value ;
1420+ $ this ->table_name = $ this -> normalize_column_name ( $ rewriter ->skip ()->value ) ;
14211421 $ rewriter ->add ( new WP_SQLite_Token ( 'SELECT ' , WP_SQLite_Token::TYPE_KEYWORD , WP_SQLite_Token::FLAG_KEYWORD_RESERVED ) );
14221422
14231423 /*
@@ -1433,7 +1433,7 @@ private function execute_delete() {
14331433 for ( $ i = $ index + 1 ; $ i < $ rewriter ->max ; $ i ++ ) {
14341434 // Assume the table name is the first token after FROM.
14351435 if ( ! $ rewriter ->input_tokens [ $ i ]->is_semantically_void () ) {
1436- $ this ->table_name = $ rewriter ->input_tokens [ $ i ]->value ;
1436+ $ this ->table_name = $ this -> normalize_column_name ( $ rewriter ->input_tokens [ $ i ]->value ) ;
14371437 break ;
14381438 }
14391439 }
@@ -1491,10 +1491,12 @@ private function execute_delete() {
14911491 $ ids_to_delete [] = $ id ['id_1 ' ];
14921492 }
14931493
1494+ $ quoted_table = $ this ->quote_identifier ( $ this ->table_name );
1495+ $ quoted_pk = $ this ->quote_identifier ( $ pk_name );
14941496 $ query = (
14951497 count ( $ ids_to_delete )
1496- ? "DELETE FROM {$ this -> table_name } WHERE {$ pk_name } IN ( " . implode ( ', ' , $ ids_to_delete ) . ') '
1497- : "DELETE FROM {$ this -> table_name } WHERE 0=1 "
1498+ ? "DELETE FROM {$ quoted_table } WHERE {$ quoted_pk } IN ( " . implode ( ', ' , $ ids_to_delete ) . ') '
1499+ : "DELETE FROM {$ quoted_table } WHERE 0=1 "
14981500 );
14991501 $ this ->execute_sqlite_query ( $ query );
15001502 $ this ->set_result_from_affected_rows (
@@ -4050,6 +4052,21 @@ private function normalize_column_name( $column_name ) {
40504052 return trim ( $ column_name , '` \'" ' );
40514053 }
40524054
4055+ /**
4056+ * Quotes an identifier for safe use in SQLite queries.
4057+ *
4058+ * Wraps the identifier in backticks and escapes any internal backticks
4059+ * by doubling them. This ensures identifiers with special characters
4060+ * are properly escaped in the target SQLite query context.
4061+ *
4062+ * @param string $identifier The unquoted identifier.
4063+ *
4064+ * @return string The properly quoted identifier.
4065+ */
4066+ private function quote_identifier ( $ identifier ) {
4067+ return '` ' . str_replace ( '` ' , '`` ' , $ identifier ) . '` ' ;
4068+ }
4069+
40534070 /**
40544071 * Normalizes an index type.
40554072 *
0 commit comments