SECURITY: Fix cache mode for (un)patrolled recent changes query
[lhc/web/wiklou.git] / includes / api / ApiQueryRecentChanges.php
index e431202..864b182 100644 (file)
@@ -192,15 +192,15 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) )
                                || ( isset( $show['patrolled'] ) && isset( $show['unpatrolled'] ) )
                                || ( isset( $show['!patrolled'] ) && isset( $show['unpatrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['!autopatrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['unpatrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['!patrolled'] ) )
                        ) {
                                $this->dieWithError( 'apierror-show' );
                        }
 
                        // Check permissions
-                       if ( isset( $show['patrolled'] )
-                               || isset( $show['!patrolled'] )
-                               || isset( $show['unpatrolled'] )
-                       ) {
+                       if ( $this->includesPatrollingFlags( $show ) ) {
                                if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
                                        $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
                                }
@@ -230,13 +230,22 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        if ( isset( $show['unpatrolled'] ) ) {
                                // See ChangesList::isUnpatrolled
                                if ( $user->useRCPatrol() ) {
-                                       $this->addWhere( 'rc_patrolled = 0' );
+                                       $this->addWhere( 'rc_patrolled = ' . RecentChange::PRC_UNPATROLLED );
                                } elseif ( $user->useNPPatrol() ) {
-                                       $this->addWhere( 'rc_patrolled = 0' );
+                                       $this->addWhere( 'rc_patrolled = ' . RecentChange::PRC_UNPATROLLED );
                                        $this->addWhereFld( 'rc_type', RC_NEW );
                                }
                        }
 
+                       $this->addWhereIf(
+                               'rc_patrolled != ' . RecentChange::PRC_AUTOPATROLLED,
+                               isset( $show['!autopatrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled = ' . RecentChange::PRC_AUTOPATROLLED,
+                               isset( $show['autopatrolled'] )
+                       );
+
                        // Don't throw log entries out the window here
                        $this->addWhereIf(
                                'page_is_redirect = 0 OR page_is_redirect IS NULL',
@@ -544,8 +553,9 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                /* Add the patrolled flag */
                if ( $this->fld_patrolled ) {
-                       $vals['patrolled'] = $row->rc_patrolled == 1;
+                       $vals['patrolled'] = $row->rc_patrolled != RecentChange::PRC_UNPATROLLED;
                        $vals['unpatrolled'] = ChangesList::isUnpatrolled( $row, $user );
+                       $vals['autopatrolled'] = $row->rc_patrolled == RecentChange::PRC_AUTOPATROLLED;
                }
 
                if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
@@ -605,13 +615,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';
@@ -694,7 +714,9 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                        '!redirect',
                                        'patrolled',
                                        '!patrolled',
-                                       'unpatrolled'
+                                       'unpatrolled',
+                                       'autopatrolled',
+                                       '!autopatrolled',
                                ]
                        ],
                        'limit' => [