From a91d6f4caca593c54e6d42588ac58e7a8351c52e Mon Sep 17 00:00:00 2001 From: Platonides Date: Tue, 12 Apr 2011 16:34:12 +0000 Subject: [PATCH] Abstract tableName() by adding new function isQuotedIdentifier() to databases. This fixes bug in DatabaseOracle.php tableName() on line 671 and allows it to call the parent implementation instead of copying it with different quotes. Adapt Mssql addIdentifierQuotes(). Replace its addIdentifierQuotes calls with addQuotes as it's what it really is. The serialize() is probably unneeded, since I don't think it will ever be called with objects but I kept it anyway. --- includes/db/Database.php | 19 +++++++++++----- includes/db/DatabaseMssql.php | 15 ++++++++++--- includes/db/DatabaseMysql.php | 4 ++++ includes/db/DatabaseOracle.php | 41 +--------------------------------- includes/db/DatabaseSqlite.php | 2 +- 5 files changed, 32 insertions(+), 49 deletions(-) diff --git a/includes/db/Database.php b/includes/db/Database.php index f6f9bb3023..3a5da57a85 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -1521,7 +1521,7 @@ abstract class DatabaseBase implements DatabaseType { # Note that we check the end so that we will still quote any use of # use of `database`.table. But won't break things if someone wants # to query a database table with a dot in the name. - if ( $name[0] == '`' && substr( $name, -1, 1 ) == '`' ) { + if ( $this->isQuotedIdentifier( $name ) ) { return $name; } @@ -1550,14 +1550,14 @@ abstract class DatabaseBase implements DatabaseType { # A database name has been specified in input. Quote the table name # because we don't want any prefixes added. if ( isset( $database ) ) { - $table = ( $table[0] == '`' ? $table : "`{$table}`" ); + $table = ( $this->isQuotedIdentifier( $table ) ? $table : $this->addIdentifierQuotes( $table ) ); } # Note that we use the long format because php will complain in in_array if # the input is not an array, and will complain in is_array if it is not set. if ( !isset( $database ) # Don't use shared database if pre selected. && isset( $wgSharedDB ) # We have a shared database - && $table[0] != '`' # Paranoia check to prevent shared tables listing '`table`' + && !$this->isQuotedIdentifier( $table ) # Paranoia check to prevent shared tables listing '`table`' && isset( $wgSharedTables ) && is_array( $wgSharedTables ) && in_array( $table, $wgSharedTables ) ) { # A shared table is selected @@ -1567,9 +1567,9 @@ abstract class DatabaseBase implements DatabaseType { # Quote the $database and $table and apply the prefix if not quoted. if ( isset( $database ) ) { - $database = ( $database[0] == '`' ? $database : "`{$database}`" ); + $database = ( $this->isQuotedIdentifier( $database ) ? $database : $this->addIdentifierQuotes( $database ) ); } - $table = ( $table[0] == '`' ? $table : "`{$prefix}{$table}`" ); + $table = ( $this->isQuotedIdentifier( $table ) ? $table : $this->addIdentifierQuotes( "{$prefix}{$table}" ) ); # Merge our database and table into our final table name. $tableName = ( isset( $database ) ? "{$database}.{$table}" : "{$table}" ); @@ -1746,6 +1746,15 @@ abstract class DatabaseBase implements DatabaseType { return '"' . str_replace( '"', '""', $s ) . '"'; } + /** + * Returns if the given identifier looks quoted or not according to + * the database convention for quoting identifiers . + * @return boolean + */ + public function isQuotedIdentifier( $name ) { + return $name[0] == '"' && substr( $name, -1, 1 ) == '"'; + } + /** * Backwards compatibility, identifier quoting originated in DatabasePostgres * which used quote_ident which does not follow our naming conventions diff --git a/includes/db/DatabaseMssql.php b/includes/db/DatabaseMssql.php index 015f5a0546..e1f265bd62 100644 --- a/includes/db/DatabaseMssql.php +++ b/includes/db/DatabaseMssql.php @@ -452,14 +452,14 @@ class DatabaseMssql extends DatabaseBase { $sql .= ','; } if ( is_string( $value ) ) { - $sql .= $this->addIdentifierQuotes( $value ); + $sql .= $this->addQuotes( $value ); } elseif ( is_null( $value ) ) { $sql .= 'null'; } elseif ( is_array( $value ) || is_object( $value ) ) { if ( is_object( $value ) && strtolower( get_class( $value ) ) == 'blob' ) { - $sql .= $this->addIdentifierQuotes( $value->fetch() ); + $sql .= $this->addQuotes( $value ); } else { - $sql .= $this->addIdentifierQuotes( serialize( $value ) ); + $sql .= $this->addQuotes( serialize( $value ) ); } } else { $sql .= $value; @@ -989,6 +989,15 @@ class DatabaseMssql extends DatabaseBase { } } + public function addIdentifierQuotes( $s ) { + // http://msdn.microsoft.com/en-us/library/aa223962.aspx + return '[' . $s . ']'; + } + + public function isQuotedIdentifier( $name ) { + return $name[0] == '[' && substr( $name, -1, 1 ) == ']'; + } + function selectDB( $db ) { return ( $this->query( "SET DATABASE $db" ) !== false ); } diff --git a/includes/db/DatabaseMysql.php b/includes/db/DatabaseMysql.php index 25c360d6d2..1289e88719 100644 --- a/includes/db/DatabaseMysql.php +++ b/includes/db/DatabaseMysql.php @@ -329,6 +329,10 @@ class DatabaseMysql extends DatabaseBase { return "`" . $this->strencode( $s ) . "`"; } + public function isQuotedIdentifier( $name ) { + return $name[0] == '`' && substr( $name, -1, 1 ) == '`'; + } + function ping() { $ping = mysql_ping( $this->mConn ); if ( $ping ) { diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php index 41faf1912d..7113d1badb 100644 --- a/includes/db/DatabaseOracle.php +++ b/includes/db/DatabaseOracle.php @@ -648,46 +648,7 @@ class DatabaseOracle extends DatabaseBase { break; } - /* - The rest of procedure is equal to generic Databse class - except for the quoting style - */ - if ( $name[0] == '"' && substr( $name, - 1, 1 ) == '"' ) { - return $name; - } - if ( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) { - return $name; - } - $dbDetails = array_reverse( explode( '.', $name, 2 ) ); - if ( isset( $dbDetails[1] ) ) { - @list( $table, $database ) = $dbDetails; - } else { - @list( $table ) = $dbDetails; - } - - $prefix = $this->mTablePrefix; - - if ( isset( $database ) ) { - $table = ( $table[0] == '`' ? $table : "`{$table}`" ); - } - - if ( !isset( $database ) && isset( $wgSharedDB ) && $table[0] != '"' - && isset( $wgSharedTables ) - && is_array( $wgSharedTables ) - && in_array( $table, $wgSharedTables ) - ) { - $database = $wgSharedDB; - $prefix = isset( $wgSharedPrefix ) ? $wgSharedPrefix : $prefix; - } - - if ( isset( $database ) ) { - $database = ( $database[0] == '"' ? $database : "\"{$database}\"" ); - } - $table = ( $table[0] == '"') ? $table : "\"{$prefix}{$table}\"" ; - - $tableName = ( isset( $database ) ? "{$database}.{$table}" : "{$table}" ); - - return strtoupper( $tableName ); + return parent::tableName( strtoupper( $name ) ); } /** diff --git a/includes/db/DatabaseSqlite.php b/includes/db/DatabaseSqlite.php index e7bc31eacc..654376a4ab 100644 --- a/includes/db/DatabaseSqlite.php +++ b/includes/db/DatabaseSqlite.php @@ -257,7 +257,7 @@ class DatabaseSqlite extends DatabaseBase { function tableName( $name ) { // table names starting with sqlite_ are reserved if ( strpos( $name, 'sqlite_' ) === 0 ) return $name; - return str_replace( '`', '', parent::tableName( $name ) ); + return str_replace( '"', '', parent::tableName( $name ) ); } /** -- 2.20.1