SECURITY: Fix cache mode for (un)patrolled recent changes query
[lhc/web/wiklou.git] / includes / api / ApiQueryRecentChanges.php
index 779d601..8ae1b66 100644 (file)
@@ -159,7 +159,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        $this->dieContinueUsageIf( count( $cont ) != 2 );
                        $db = $this->getDB();
                        $timestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
-                       $id = intval( $cont[1] );
+                       $id = (int)$cont[1];
                        $this->dieContinueUsageIf( $id != $cont[1] );
                        $op = $params['dir'] === 'older' ? '<' : '>';
                        $this->addWhere(
@@ -214,12 +214,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        }
 
                        // Check permissions
-                       if ( isset( $show['patrolled'] )
-                               || isset( $show['!patrolled'] )
-                               || isset( $show['unpatrolled'] )
-                               || isset( $show['autopatrolled'] )
-                               || isset( $show['!autopatrolled'] )
-                       ) {
+                       if ( $this->includesPatrollingFlags( $show ) ) {
                                if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
                                        $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
                                }
@@ -360,7 +355,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
-                       $this->addJoinConds( [ 'change_tag' => [ 'INNER JOIN', [ 'rc_id=ct_rc_id' ] ] ] );
+                       $this->addJoinConds( [ 'change_tag' => [ 'JOIN', [ 'rc_id=ct_rc_id' ] ] ] );
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        try {
                                $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
@@ -483,7 +478,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                /* Our output data. */
                $vals = [];
 
-               $type = intval( $row->rc_type );
+               $type = (int)$row->rc_type;
                $vals['type'] = RecentChange::parseFromRCType( $type );
 
                $anyHidden = false;
@@ -501,15 +496,15 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                        ApiQueryBase::addTitleInfo( $vals, $title );
                                }
                                if ( $this->fld_ids ) {
-                                       $vals['pageid'] = intval( $row->rc_cur_id );
-                                       $vals['revid'] = intval( $row->rc_this_oldid );
-                                       $vals['old_revid'] = intval( $row->rc_last_oldid );
+                                       $vals['pageid'] = (int)$row->rc_cur_id;
+                                       $vals['revid'] = (int)$row->rc_this_oldid;
+                                       $vals['old_revid'] = (int)$row->rc_last_oldid;
                                }
                        }
                }
 
                if ( $this->fld_ids ) {
-                       $vals['rcid'] = intval( $row->rc_id );
+                       $vals['rcid'] = (int)$row->rc_id;
                }
 
                /* Add user data and 'anon' flag, if user is anonymous. */
@@ -542,8 +537,8 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                /* Add sizes of each revision. (Only available on 1.10+) */
                if ( $this->fld_sizes ) {
-                       $vals['oldlen'] = intval( $row->rc_old_len );
-                       $vals['newlen'] = intval( $row->rc_new_len );
+                       $vals['oldlen'] = (int)$row->rc_old_len;
+                       $vals['newlen'] = (int)$row->rc_new_len;
                }
 
                /* Add the timestamp. */
@@ -588,7 +583,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                $anyHidden = true;
                        }
                        if ( LogEventsList::userCanBitfield( $row->rc_deleted, LogPage::DELETED_ACTION, $user ) ) {
-                               $vals['logid'] = intval( $row->rc_logid );
+                               $vals['logid'] = (int)$row->rc_logid;
                                $vals['logtype'] = $row->rc_log_type;
                                $vals['logaction'] = $row->rc_log_action;
                                $vals['logparams'] = LogFormatter::newFromRow( $row )->formatParametersForApi();
@@ -641,13 +636,23 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                return $vals;
        }
 
+       /**
+        * @param array $flagsArray flipped array (string flags are keys)
+        * @return bool
+        */
+       private function includesPatrollingFlags( array $flagsArray ) {
+               return isset( $flagsArray['patrolled'] ) ||
+                       isset( $flagsArray['!patrolled'] ) ||
+                       isset( $flagsArray['unpatrolled'] ) ||
+                       isset( $flagsArray['autopatrolled'] ) ||
+                       isset( $flagsArray['!autopatrolled'] );
+       }
+
        public function getCacheMode( $params ) {
-               if ( isset( $params['show'] ) ) {
-                       foreach ( $params['show'] as $show ) {
-                               if ( $show === 'patrolled' || $show === '!patrolled' ) {
-                                       return 'private';
-                               }
-                       }
+               if ( isset( $params['show'] ) &&
+                       $this->includesPatrollingFlags( array_flip( $params['show'] ) )
+               ) {
+                       return 'private';
                }
                if ( isset( $params['token'] ) ) {
                        return 'private';