From 0fe5a64e5645cf7769f9c6408bd349c517f148ca Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Tue, 21 Apr 2015 05:10:11 +0000 Subject: [PATCH] WPDB: When deciding if a query needs extra sanity checking based on collation, we can quickly return if it's a query that will never return user data. Fixes #32029. git-svn-id: https://develop.svn.wordpress.org/trunk@32232 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/wp-db.php | 14 +++++++++++++- tests/phpunit/tests/db/charset.php | 13 ++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/wp-db.php b/src/wp-includes/wp-db.php index cdb9eda8c8..7dd81b89cc 100644 --- a/src/wp-includes/wp-db.php +++ b/src/wp-includes/wp-db.php @@ -2399,20 +2399,32 @@ class wpdb { return true; } + // We don't need to check the collation for queries that don't read data. + $query = ltrim( $query, "\r\n\t (" ); + if ( preg_match( '/^(?:SHOW|DESCRIBE|DESC|EXPLAIN)\s/i', $query ) ) { + return true; + } + $table = $this->get_table_from_query( $query ); if ( ! $table ) { return false; } $this->checking_collation = true; - $this->get_table_charset( $table ); + $collation = $this->get_table_charset( $table ); $this->checking_collation = false; + // Tables with no collation, or latin1 only, don't need extra checking. + if ( false === $collation || 'latin1' === $collation ) { + return true; + } + $table = strtolower( $table ); if ( empty( $this->col_meta[ $table ] ) ) { return false; } + // If any of the columns don't have one of these collations, it needs more sanity checking. foreach( $this->col_meta[ $table ] as $col ) { if ( empty( $col->Collation ) ) { continue; diff --git a/tests/phpunit/tests/db/charset.php b/tests/phpunit/tests/db/charset.php index dc5f428917..d55c750c66 100755 --- a/tests/phpunit/tests/db/charset.php +++ b/tests/phpunit/tests/db/charset.php @@ -505,6 +505,12 @@ class Tests_DB_Charset extends WP_UnitTestCase { $value[0] = "CREATE TABLE $this_table_name {$value[0]}"; $value[2] = "SELECT * FROM $this_table_name"; $value[3] = "DROP TABLE IF EXISTS $this_table_name"; + $value[4] = array( + "SHOW FULL TABLES LIKE $this_table_name", + "DESCRIBE $this_table_name", + "DESC $this_table_name", + "EXPLAIN SELECT * FROM $this_table_name", + ); } unset( $value ); @@ -516,7 +522,7 @@ class Tests_DB_Charset extends WP_UnitTestCase { * @dataProvider data_table_collation_check * @ticket 21212 */ - function test_table_collation_check( $create, $expected, $query, $drop ) { + function test_table_collation_check( $create, $expected, $query, $drop, $always_true ) { self::$_wpdb->query( $drop ); self::$_wpdb->query( $create ); @@ -524,6 +530,11 @@ class Tests_DB_Charset extends WP_UnitTestCase { $return = self::$_wpdb->check_safe_collation( $query ); $this->assertEquals( $expected, $return ); + foreach( $always_true as $true_query ) { + $return = self::$_wpdb->check_safe_collation( $true_query ); + $this->assertTrue( $return ); + } + self::$_wpdb->query( $drop ); } }