Skip to content

Commit b447337

Browse files
authored
Merge pull request #59 from wp-cli/58-fix-regex-table-quoting
Quote SQL values in --regex code
2 parents 32416f8 + 9c973d2 commit b447337

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

features/search-replace.feature

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,3 +977,33 @@ Feature: Do global search/replace
977977
> Just another WP site
978978
"""
979979
And STDERR should be empty
980+
981+
# Regression test for https://github.com/wp-cli/search-replace-command/issues/58
982+
Scenario: The parameters --regex and --all-tables-with-prefix produce valid SQL
983+
Given a WP install
984+
And a test_db.sql file:
985+
"""
986+
DROP TABLE IF EXISTS `wp_123_test`;
987+
CREATE TABLE `wp_123_test` (
988+
`name` varchar(50),
989+
`value` varchar(5000),
990+
`created_at` datetime NOT NULL,
991+
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
992+
PRIMARY KEY (`name`)
993+
) ENGINE=InnoDB;
994+
INSERT INTO `wp_123_test` VALUES ('test_val','off','2016-11-15 14:41:33','2016-11-15 21:41:33');
995+
INSERT INTO `wp_123_test` VALUES ('123.','off','2016-11-15 14:41:33','2016-11-15 21:41:33');
996+
INSERT INTO `wp_123_test` VALUES ('quote\'quote','off','2016-11-15 14:41:33','2016-11-15 21:41:33');
997+
INSERT INTO `wp_123_test` VALUES ('0','off','2016-11-15 14:41:33','2016-11-15 21:41:33');
998+
INSERT INTO `wp_123_test` VALUES ('','off','2016-11-15 14:41:33','2016-11-15 21:41:33');
999+
"""
1000+
1001+
When I run `wp db query "SOURCE test_db.sql;"`
1002+
Then STDERR should be empty
1003+
1004+
When I run `wp search-replace --dry-run --regex 'mytestdomain.com\/' 'mytestdomain2.com/' --all-tables-with-prefix --skip-columns=guid,domain`
1005+
Then STDERR should be empty
1006+
And STDOUT should contain:
1007+
"""
1008+
Success: 0 replacements to be made.
1009+
"""

src/Search_Replace_Command.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) {
492492
if ( strlen( $where_sql ) ) {
493493
$where_sql .= ' AND ';
494494
}
495-
$where_sql .= self::esc_sql_ident( $k ) . ' = ' . esc_sql( $v );
495+
$where_sql .= self::esc_sql_ident( $k ) . ' = ' . self::esc_sql_value( $v );
496496
}
497497
$col_value = $wpdb->get_var( "SELECT {$col_sql} FROM {$table_sql} WHERE {$where_sql}" );
498498
if ( '' === $col_value )
@@ -649,6 +649,30 @@ private static function esc_sql_ident( $idents ) {
649649
return array_map( $backtick, $idents );
650650
}
651651

652+
/**
653+
* Puts MySQL string values in single quotes, to avoid them being interpreted as column names.
654+
*
655+
* @param string|array $values A single value or an array of values.
656+
* @return string|array A quoted string if given a string, or an array of quoted strings if given an array of strings.
657+
*/
658+
private static function esc_sql_value( $values ) {
659+
$quote = function ( $v ) {
660+
// Don't quote integer values to avoid MySQL's implicit type conversion.
661+
if ( (string)(int) $v === (string) $v ) {
662+
return esc_sql( $v );
663+
}
664+
665+
// Put any string values between single quotes.
666+
return "'" . esc_sql( $v ) . "'";
667+
};
668+
669+
if ( is_array( $values ) ) {
670+
return array_map( $quote, $values );
671+
}
672+
673+
return $quote( $values );
674+
}
675+
652676
/**
653677
* Gets the color codes from the options if any, and returns the passed in array colorized with 2 elements per entry, a color code (or '') and a reset (or '').
654678
*

0 commit comments

Comments
 (0)