SECURITY: quote booleans as string (not integer) in DatabaseMysqlBase
[lhc/web/wiklou.git] / includes / libs / rdbms / database / DatabaseMysqlBase.php
index 7f67b6e..b1c18b6 100644 (file)
@@ -29,7 +29,7 @@
  * @since 1.22
  * @see Database
  */
-abstract class DatabaseMysqlBase extends DatabaseBase {
+abstract class DatabaseMysqlBase extends Database {
        /** @var MysqlMasterPos */
        protected $lastKnownReplicaPos;
        /** @var string Method to detect replica DB lag */
@@ -608,6 +608,16 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         */
        abstract protected function mysqlRealEscapeString( $s );
 
+       public function addQuotes( $s ) {
+               if ( is_bool( $s ) ) {
+                       // Parent would transform to int, which does not play nice with MySQL type juggling.
+                       // When searching for an int in a string column, the strings are cast to int, which
+                       // means false would match any string not starting with a number.
+                       $s = (string)(int)$s;
+               }
+               return parent::addQuotes( $s );
+       }
+
        /**
         * MySQL uses `backticks` for identifier quoting instead of the sql standard "double quotes".
         *
@@ -811,7 +821,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        // with an old master hostname. Such calls make MASTER_POS_WAIT() return null. Try
                        // to detect this and treat the replica DB as having reached the position; a proper master
                        // switchover already requires that the new master be caught up before the switch.
-                       $replicationPos = $this->getSlavePos();
+                       $replicationPos = $this->getReplicaPos();
                        if ( $replicationPos && !$replicationPos->channelsMatch( $pos ) ) {
                                $this->lastKnownReplicaPos = $replicationPos;
                                $status = 0;
@@ -829,7 +839,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         *
         * @return MySQLMasterPos|bool
         */
-       function getSlavePos() {
+       function getReplicaPos() {
                $res = $this->query( 'SHOW SLAVE STATUS', __METHOD__ );
                $row = $this->fetchObject( $res );
 
@@ -973,8 +983,8 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @since 1.20
         */
        public function lockIsFree( $lockName, $method ) {
-               $lockName = $this->addQuotes( $this->makeLockName( $lockName ) );
-               $result = $this->query( "SELECT IS_FREE_LOCK($lockName) AS lockstatus", $method );
+               $encName = $this->addQuotes( $this->makeLockName( $lockName ) );
+               $result = $this->query( "SELECT IS_FREE_LOCK($encName) AS lockstatus", $method );
                $row = $this->fetchObject( $result );
 
                return ( $row->lockstatus == 1 );
@@ -987,8 +997,8 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @return bool
         */
        public function lock( $lockName, $method, $timeout = 5 ) {
-               $lockName = $this->addQuotes( $this->makeLockName( $lockName ) );
-               $result = $this->query( "SELECT GET_LOCK($lockName, $timeout) AS lockstatus", $method );
+               $encName = $this->addQuotes( $this->makeLockName( $lockName ) );
+               $result = $this->query( "SELECT GET_LOCK($encName, $timeout) AS lockstatus", $method );
                $row = $this->fetchObject( $result );
 
                if ( $row->lockstatus == 1 ) {
@@ -1009,8 +1019,8 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @return bool
         */
        public function unlock( $lockName, $method ) {
-               $lockName = $this->addQuotes( $this->makeLockName( $lockName ) );
-               $result = $this->query( "SELECT RELEASE_LOCK($lockName) as lockstatus", $method );
+               $encName = $this->addQuotes( $this->makeLockName( $lockName ) );
+               $result = $this->query( "SELECT RELEASE_LOCK($encName) as lockstatus", $method );
                $row = $this->fetchObject( $result );
 
                if ( $row->lockstatus == 1 ) {
@@ -1269,21 +1279,6 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                return $this->query( "DROP TABLE IF EXISTS " . $this->tableName( $tableName ), $fName );
        }
 
-       /**
-        * @return array
-        */
-       protected function getDefaultSchemaVars() {
-               $vars = parent::getDefaultSchemaVars();
-               $vars['wgDBTableOptions'] = str_replace( 'TYPE', 'ENGINE', $GLOBALS['wgDBTableOptions'] );
-               $vars['wgDBTableOptions'] = str_replace(
-                       'CHARSET=mysql4',
-                       'CHARSET=binary',
-                       $vars['wgDBTableOptions']
-               );
-
-               return $vars;
-       }
-
        /**
         * Get status information from SHOW STATUS in an associative array
         *
@@ -1311,26 +1306,22 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @since 1.22
         */
        public function listViews( $prefix = null, $fname = __METHOD__ ) {
+               // The name of the column containing the name of the VIEW
+               $propertyName = 'Tables_in_' . $this->mDBname;
 
-               if ( !isset( $this->allViews ) ) {
-
-                       // The name of the column containing the name of the VIEW
-                       $propertyName = 'Tables_in_' . $this->mDBname;
-
-                       // Query for the VIEWS
-                       $result = $this->query( 'SHOW FULL TABLES WHERE TABLE_TYPE = "VIEW"' );
-                       $this->allViews = [];
-                       while ( ( $row = $this->fetchRow( $result ) ) !== false ) {
-                               array_push( $this->allViews, $row[$propertyName] );
-                       }
+               // Query for the VIEWS
+               $res = $this->query( 'SHOW FULL TABLES WHERE TABLE_TYPE = "VIEW"' );
+               $allViews = [];
+               foreach ( $res as $row ) {
+                       array_push( $allViews, $row->$propertyName );
                }
 
                if ( is_null( $prefix ) || $prefix === '' ) {
-                       return $this->allViews;
+                       return $allViews;
                }
 
                $filteredViews = [];
-               foreach ( $this->allViews as $viewName ) {
+               foreach ( $allViews as $viewName ) {
                        // Does the name of this VIEW start with the table-prefix?
                        if ( strpos( $viewName, $prefix ) === 0 ) {
                                array_push( $filteredViews, $viewName );