diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 5edf04dd14f..bcbff5cf0f8 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -3278,7 +3278,6 @@ class OutputPage extends ContextSource { // Get the relevant title so that AJAX features can use the correct page name // when making API requests from certain special pages (T36972). $relevantTitle = $sk->getRelevantTitle(); - $relevantUser = $sk->getRelevantUser(); if ( $ns === NS_SPECIAL ) { list( $canonicalSpecialPageName, /*...*/ ) = @@ -3379,11 +3378,9 @@ class OutputPage extends ContextSource { if ( $title->isMainPage() ) { $vars['wgIsMainPage'] = true; } - if ( $relevantUser && ( !$relevantUser->isHidden() || - $this->getAuthority()->isAllowed( 'hideuser' ) ) - ) { - // T120883 if the user is hidden and the viewer cannot see - // hidden users, pretend like it does not exist at all. + + $relevantUser = $sk->getRelevantUser(); + if ( $relevantUser ) { $vars['wgRelevantUserName'] = $relevantUser->getName(); } // End of stable config vars diff --git a/includes/skins/Skin.php b/includes/skins/Skin.php index 0e214b2b369..bc7f575ad8b 100644 --- a/includes/skins/Skin.php +++ b/includes/skins/Skin.php @@ -52,6 +52,10 @@ abstract class Skin extends ContextSource { */ protected $options = []; protected $mRelevantTitle = null; + + /** + * @var User|null + */ protected $mRelevantUser = null; /** @@ -415,7 +419,7 @@ abstract class Skin extends ContextSource { * @see self::getRelevantUser() * @param User $u */ - public function setRelevantUser( $u ) { + public function setRelevantUser( User $u ) { $this->mRelevantUser = $u; } @@ -425,31 +429,40 @@ abstract class Skin extends ContextSource { * Special:Contributions mark the user which they are relevant to so that * things like the toolbox can display the information they usually are only * able to display on a user's userpage and talkpage. - * @return User + * + * @return User|null Null if there's no relevant user or the viewer cannot view it. */ public function getRelevantUser() { - if ( isset( $this->mRelevantUser ) ) { - return $this->mRelevantUser; - } - $title = $this->getRelevantTitle(); - if ( $title->hasSubjectNamespace( NS_USER ) ) { - $rootUser = $title->getRootText(); - if ( User::isIP( $rootUser ) ) { - $this->mRelevantUser = User::newFromName( $rootUser, false ); - } else { - $user = User::newFromName( $rootUser, false ); + if ( $this->mRelevantUser === null ) { + $title = $this->getRelevantTitle(); + if ( $title->hasSubjectNamespace( NS_USER ) ) { + $rootUser = $title->getRootText(); + if ( User::isIP( $rootUser ) ) { + $this->mRelevantUser = User::newFromName( $rootUser, false ); + } else { + $user = User::newFromName( $rootUser, false ); - if ( $user ) { - $user->load( User::READ_NORMAL ); - - if ( $user->isRegistered() ) { - $this->mRelevantUser = $user; + if ( $user ) { + $user->load( User::READ_NORMAL ); + $this->mRelevantUser = $user->isRegistered() ? $user : null; } } } - return $this->mRelevantUser; } - return null; + + $pm = MediaWikiServices::getInstance()->getPermissionManager(); + // The relevant user should only be set if it exists. However, if it exists but is hidden, + // and the viewer cannot see hidden users, this exposes the fact that the user exists; + // pretend like the user does not exist in such cases, by setting it to null. T120883 + if ( $this->mRelevantUser + && $this->mRelevantUser->isRegistered() + && $this->mRelevantUser->isHidden() + && !$pm->userHasRight( $this->getUser(), 'hideuser' ) + ) { + return null; + } + + return $this->mRelevantUser; } /** diff --git a/includes/specials/SpecialListFiles.php b/includes/specials/SpecialListFiles.php index bd5d62abba4..7b7ff187d15 100644 --- a/includes/specials/SpecialListFiles.php +++ b/includes/specials/SpecialListFiles.php @@ -123,7 +123,9 @@ class SpecialListFiles extends IncludableSpecialPage { $out->addParserOutputContent( $pager->getBodyOutput() ); } else { $user = $pager->getRelevantUser(); - $this->getSkin()->setRelevantUser( $user ); + if ( $user ) { + $this->getSkin()->setRelevantUser( $user ); + } $pager->getForm(); $out->addParserOutputContent( $pager->getFullOutput() ); } diff --git a/includes/specials/SpecialLog.php b/includes/specials/SpecialLog.php index 253b9d3707a..e08b6ddfe65 100644 --- a/includes/specials/SpecialLog.php +++ b/includes/specials/SpecialLog.php @@ -256,7 +256,9 @@ class SpecialLog extends SpecialPage { # Set relevant user if ( $pager->getPerformer() ) { $performerUser = User::newFromName( $pager->getPerformer(), false ); - $this->getSkin()->setRelevantUser( $performerUser ); + if ( $performerUser ) { + $this->getSkin()->setRelevantUser( $performerUser ); + } } # Show form options