From de33d35d1f9ea6da45259b172d617bfcb07073d9 Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Tue, 18 Nov 2014 03:37:23 +0000 Subject: [PATCH] WPDB: When a `db.php` drop-in is being used, and it doesn't explicitly define itself as connecting to MySQL, skip the character set checks. This ensures that existing drop-ins won't accidentally run checks that they don't support. See #21212. git-svn-id: https://develop.svn.wordpress.org/trunk@30375 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/wp-db.php | 16 ++++++++++------ tests/phpunit/tests/db/charset.php | 28 +++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/wp-db.php b/src/wp-includes/wp-db.php index e297152092..924ea5dcc0 100644 --- a/src/wp-includes/wp-db.php +++ b/src/wp-includes/wp-db.php @@ -2211,7 +2211,7 @@ class wpdb { $this->col_meta[ $table ] = $columns; foreach ( $columns as $column ) { - if ( $column->Collation ) { + if ( ! empty( $column->Collation ) ) { list( $charset ) = explode( '_', $column->Collation ); $charsets[ strtolower( $charset ) ] = true; } @@ -2237,7 +2237,7 @@ class wpdb { $charset = key( $charsets ); } elseif ( 0 === $count ) { // No charsets, assume this table can store whatever. - $charset = 'latin1'; + $charset = false; } else { // More than one charset. Remove latin1 if present and recalculate. unset( $charsets['latin1'] ); @@ -2291,6 +2291,11 @@ class wpdb { return $charset; } + // Skip this entirely if this isn't a MySQL database. + if ( false === $this->is_mysql ) { + return false; + } + if ( empty( $this->table_charset[ $table ] ) ) { // This primes column information for us. $table_charset = $this->get_table_charset( $table ); @@ -2378,13 +2383,12 @@ class wpdb { foreach ( $data as &$value ) { $charset = $value['charset']; - // latin1 will happily store anything. - if ( 'latin1' === $charset ) { + // Column isn't a string, or is latin1, which will will happily store anything. + if ( false === $charset || 'latin1' === $charset ) { continue; } - // Column or value isn't a string. - if ( false === $charset || ! is_string( $value['value'] ) ) { + if ( ! is_string( $value['value'] ) ) { continue; } diff --git a/tests/phpunit/tests/db/charset.php b/tests/phpunit/tests/db/charset.php index fcad682e04..00f6e0b963 100755 --- a/tests/phpunit/tests/db/charset.php +++ b/tests/phpunit/tests/db/charset.php @@ -231,7 +231,7 @@ class Tests_DB_Charset extends WP_UnitTestCase { protected $table_and_column_defs = array( array( 'definition' => '( a INT, b FLOAT )', - 'table_expected' => 'latin1', + 'table_expected' => false, 'column_expected' => array( 'a' => false, 'b' => false ) ), array( @@ -346,6 +346,32 @@ class Tests_DB_Charset extends WP_UnitTestCase { self::$_wpdb->query( $drop ); } + /** + * @dataProvider data_test_get_column_charset + * @ticket 21212 + */ + function test_get_column_charset_non_mysql( $drop, $create, $table, $columns ) { + self::$_wpdb->query( $drop ); + + if ( ! self::$_wpdb->has_cap( 'utf8mb4' ) && preg_match( '/utf8mb[34]/i', $create ) ) { + $this->markTestSkipped( "This version of MySQL doesn't support utf8mb4." ); + return; + } + + self::$_wpdb->is_mysql = false; + + self::$_wpdb->query( $create ); + + $columns = array_keys( $columns ); + foreach ( $columns as $column => $charset ) { + $this->assertEquals( false, self::$_wpdb->get_col_charset( $table, $column ) ); + } + + self::$_wpdb->query( $drop ); + + self::$_wpdb->is_mysql = true; + } + /** * @ticket 21212 */