@@ -303,22 +303,31 @@ protected function sqlite_export( $file, $assoc_args ) {
303303
304304 $ exclude_tables = array_unique ( array_filter ( $ exclude_tables ) );
305305
306- $ command = "sqlite3 $ temp_db " ;
306+ // Build DROP TABLE statements with safely-escaped identifiers.
307+ $ drop_statements = array ();
307308 foreach ( $ exclude_tables as $ table ) {
308- $ command .= sprintf ( '"DROP TABLE %s;" ' , $ table );
309+ // Escape double quotes within the table name and wrap it in double quotes.
310+ $ escaped_identifier = '" ' . str_replace ( '" ' , '"" ' , $ table ) . '" ' ;
311+ $ drop_statements [] = sprintf ( 'DROP TABLE %s; ' , $ escaped_identifier );
309312 }
310313
311- $ command = trim ( $ command );
314+ if ( ! empty ( $ drop_statements ) ) {
315+ // Build the sqlite3 command with properly escaped shell arguments.
316+ $ args = array_merge ( array ( 'sqlite3 ' , $ temp_db ), $ drop_statements );
317+ $ placeholders = array_fill ( 0 , count ( $ args ), '%s ' );
318+ $ command = Utils \esc_cmd ( implode ( ' ' , $ placeholders ), ...$ args );
312319
313- WP_CLI ::debug ( "Running shell command: {$ command }" , 'db ' );
320+ WP_CLI ::debug ( "Running shell command: {$ command }" , 'db ' );
314321
315- $ result = \WP_CLI \Process::create ( $ command , null , null )->run ();
322+ $ result = \WP_CLI \Process::create ( $ command , null , null )->run ();
316323
317- if ( 0 !== $ result ->return_code ) {
318- WP_CLI ::error ( 'Could not export database ' );
324+ if ( 0 !== $ result ->return_code ) {
325+ WP_CLI ::error ( 'Could not export database ' );
326+ }
319327 }
320328
321- $ command = "sqlite3 $ temp_db .dump > $ export_db " ;
329+ // Dump the database to the export file.
330+ $ command = Utils \esc_cmd ( 'sqlite3 %s .dump > %s ' , $ temp_db , $ export_db );
322331
323332 WP_CLI ::debug ( "Running shell command: {$ command }" , 'db ' );
324333
0 commit comments