@@ -107,24 +107,20 @@ protected function sqlite_create() {
107107 }
108108 $ db_dir = dirname ( $ db_path );
109109
110- // Create directory if it doesn't exist.
111110 if ( ! is_dir ( $ db_dir ) ) {
112111 if ( ! mkdir ( $ db_dir , 0755 , true ) ) {
113112 WP_CLI ::error ( "Could not create directory: {$ db_dir }" );
114113 }
115114 }
116115
117- // Check if database already exists.
118116 if ( file_exists ( $ db_path ) ) {
119117 WP_CLI ::error ( 'Database already exists. ' );
120118 }
121119
122- // Check if sqlite3 binary is available.
123120 if ( ! $ this ->is_sqlite3_available () ) {
124121 WP_CLI ::error ( 'The sqlite3 CLI binary is required but not found. Please install SQLite3. ' );
125122 }
126123
127- // Use Utils\esc_cmd to properly escape the command and arguments.
128124 $ command = Utils \esc_cmd ( 'sqlite3 %s %s ' , $ db_path , '' );
129125
130126 WP_CLI ::debug ( "Running shell command: {$ command }" , 'db ' );
@@ -184,12 +180,10 @@ protected function sqlite_reset() {
184180 }
185181 }
186182
187- // Check if sqlite3 binary is available.
188183 if ( ! $ this ->is_sqlite3_available () ) {
189184 WP_CLI ::error ( 'The sqlite3 CLI binary is required but not found. Please install SQLite3. ' );
190185 }
191186
192- // Use Utils\esc_cmd to properly escape the command and arguments.
193187 $ command = Utils \esc_cmd ( 'sqlite3 %s %s ' , $ db_path , '' );
194188
195189 WP_CLI ::debug ( "Running shell command: {$ command }" , 'db ' );
@@ -334,13 +328,11 @@ protected function sqlite_export( $file, $assoc_args ) {
334328 // Build DROP TABLE statements with safely-escaped identifiers.
335329 $ drop_statements = array ();
336330 foreach ( $ exclude_tables as $ table ) {
337- // Escape double quotes within the table name and wrap it in double quotes.
338331 $ escaped_identifier = '" ' . str_replace ( '" ' , '"" ' , $ table ) . '" ' ;
339332 $ drop_statements [] = sprintf ( 'DROP TABLE %s; ' , $ escaped_identifier );
340333 }
341334
342335 if ( ! empty ( $ drop_statements ) ) {
343- // Build the sqlite3 command with properly escaped shell arguments.
344336 $ args = array_merge ( array ( 'sqlite3 ' , $ temp_db ), $ drop_statements );
345337 $ placeholders = array_fill ( 0 , count ( $ args ), '%s ' );
346338 $ command = Utils \esc_cmd ( implode ( ' ' , $ placeholders ), ...$ args );
@@ -354,7 +346,6 @@ protected function sqlite_export( $file, $assoc_args ) {
354346 }
355347 }
356348
357- // Dump the database to the export file.
358349 $ command = Utils \esc_cmd ( 'sqlite3 %s .dump > %s ' , $ temp_db , $ export_db );
359350
360351 WP_CLI ::debug ( "Running shell command: {$ command }" , 'db ' );
@@ -408,8 +399,6 @@ protected function sqlite_import( $file, $assoc_args ) {
408399 WP_CLI ::error ( 'Database does not exist. ' );
409400 }
410401
411- $ contents = (string ) file_get_contents ( $ file );
412-
413402 if ( '- ' === $ file ) {
414403 $ contents = file_get_contents ( 'php://stdin ' );
415404 if ( false === $ contents ) {
@@ -419,13 +408,18 @@ protected function sqlite_import( $file, $assoc_args ) {
419408 $ file = 'STDIN ' ;
420409 } elseif ( ! is_readable ( $ file ) ) {
421410 WP_CLI ::error ( sprintf ( 'Import file missing or not readable: %s ' , $ file ) );
411+ } else {
412+ $ contents = (string ) file_get_contents ( $ file );
422413 }
423414
424415 // Ignore errors about unique constraints and existing indexes.
425416 $ contents = str_replace ( 'INSERT INTO ' , 'INSERT OR IGNORE INTO ' , $ contents );
426417 $ contents = str_replace ( 'CREATE INDEX " ' , 'CREATE INDEX IF NOT EXISTS " ' , $ contents );
427418 $ contents = str_replace ( 'CREATE UNIQUE INDEX " ' , 'CREATE UNIQUE INDEX IF NOT EXISTS " ' , $ contents );
428419
420+ $ import_file = tempnam ( sys_get_temp_dir (), 'temp.db ' );
421+ file_put_contents ( $ import_file , $ contents );
422+
429423 // Build sqlite3 command as an argument array to avoid shell injection.
430424 $ command = array ( 'sqlite3 ' );
431425
@@ -440,15 +434,14 @@ protected function sqlite_import( $file, $assoc_args ) {
440434 $ command [] = 'PRAGMA journal_mode=MEMORY; ' ;
441435 }
442436
443- // Add database path as final argument.
444- $ command[] = $ db_path ;
437+ $ command = implode ( ' ' , array_map ( ' escapeshellarg ' , $ command ) );
438+ $ command .= ' ' . escapeshellarg ( $ db_path ) . ' < ' . escapeshellarg ( $ import_file ) ;
445439
446- // For debugging, show a safely escaped shell-like representation.
447- $ debug_command = implode ( ' ' , array_map ( ' escapeshellarg ' , $ command ) );
448- WP_CLI :: debug ( " Running shell command: { $ debug_command }" , ' db ' );
440+ WP_CLI :: debug ( " Running shell command: { $ command }" , ' db ' );
441+
442+ $ result = \ WP_CLI \Process:: create ( $ command, null , null )-> run ( );
449443
450- // Pass the SQL contents via stdin instead of using shell redirection.
451- $ result = \WP_CLI \Process::create ( $ command , null , null , null , array ( 'stdin ' => $ contents ) )->run ();
444+ unlink ( $ import_file );
452445
453446 if ( 0 !== $ result ->return_code ) {
454447 WP_CLI ::error ( 'Could not import database. ' );
0 commit comments