From 923c6c981bec3da7e012a85b92b2ee26e0ee1be9 Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Wed, 6 May 2015 05:00:39 +0000 Subject: [PATCH] WPDB: Allow queries to reference tables in the `dbname.tablename` format, and allow table names to contain any valid character, rather than just ASCII. Props pento, willstedt for the initial patch. See #32090. git-svn-id: https://develop.svn.wordpress.org/trunk@32368 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/wp-db.php | 17 ++++++++++------- tests/phpunit/tests/db.php | 10 ++++++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/wp-db.php b/src/wp-includes/wp-db.php index 4be05e6ec6..c6ceabab1c 100644 --- a/src/wp-includes/wp-db.php +++ b/src/wp-includes/wp-db.php @@ -2266,7 +2266,10 @@ class wpdb { } $charsets = $columns = array(); - $results = $this->get_results( "SHOW FULL COLUMNS FROM `$table`" ); + + $table_parts = explode( '.', $table ); + $table = '`' . implode( '`.`', $table_parts ) . '`'; + $results = $this->get_results( "SHOW FULL COLUMNS FROM $table" ); if ( ! $results ) { return new WP_Error( 'wpdb_get_table_charset_failure' ); } @@ -2838,16 +2841,16 @@ class wpdb { . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?' . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?' . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:\s+FROM)?' - . ')\s+`?([\w-]+)`?/is', $query, $maybe ) ) { - return $maybe[1]; + . ')\s+((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)/is', $query, $maybe ) ) { + return str_replace( '`', '', $maybe[1] ); } // SHOW TABLE STATUS and SHOW TABLES if ( preg_match( '/^\s*(?:' . 'SHOW\s+TABLE\s+STATUS.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)' . '|SHOW\s+(?:FULL\s+)?TABLES.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)' - . ')\W([\w-]+)\W/is', $query, $maybe ) ) { - return $maybe[1]; + . ')\W((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)\W/is', $query, $maybe ) ) { + return str_replace( '`', '', $maybe[1] ); } // Big pattern for the rest of the table-related queries. @@ -2865,8 +2868,8 @@ class wpdb { . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE' . '|(?:GRANT|REVOKE).*ON\s+TABLE' . '|SHOW\s+(?:.*FROM|.*TABLE)' - . ')\s+\(*\s*`?([\w-]+)`?\s*\)*/is', $query, $maybe ) ) { - return $maybe[1]; + . ')\s+\(*\s*((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is', $query, $maybe ) ) { + return str_replace( '`', '', $maybe[1] ); } return false; diff --git a/tests/phpunit/tests/db.php b/tests/phpunit/tests/db.php index ce0a4a519d..a8524aa2cb 100644 --- a/tests/phpunit/tests/db.php +++ b/tests/phpunit/tests/db.php @@ -526,6 +526,7 @@ class Tests_DB extends WP_UnitTestCase { */ function data_get_table_from_query() { $table = 'a_test_table_name'; + $db_table = '`a_test_db`.`another_test_table`'; $queries = array( // Basic @@ -628,8 +629,13 @@ class Tests_DB extends WP_UnitTestCase { "SHOW INDEX FROM $table", ); - foreach ( $queries as &$query ) { - $query = array( $query, $table ); + $querycount = count( $queries ); + for ( $ii = 0; $ii < $querycount; $ii++ ) { + $db_query = str_replace( $table, $db_table, $queries[ $ii ] ); + $expected_db_table = str_replace( '`', '', $db_table ); + + $queries[ $ii ] = array( $queries[ $ii ], $table ); + $queries[] = array( $db_query, $expected_db_table ); } return $queries; }