From b27e460b26d95c0b89b13cfd66d9a52a143eca2a Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Wed, 19 Nov 2014 12:51:27 -0500 Subject: [PATCH] Make Title::makeTitleSafe() not need user variant In trying to avoid hitting RequestContext::getLanguage() from a call to User::idFromName(), I05aacd30 made it no longer safe for user input. A closer analysis of the call stack involved reveals that Title::makeTitleSafe() is constructing a prefixed dbkey using the localized name for NS_USER, and then Language::getNsIndex() is needing to get the variant in order to handle that localized name. But if we use the canonical name for NS_USER, Language::getNsIndex() short-circuits and skips the problematic code path. And it turns out that it doesn't actually matter which prefix Title::makeTitleSafe() uses, since the prefix doesn't make it anywhere into the resulting Title object. So let's revert I05aacd30 and Ibeef0409 and just do that instead. Change-Id: Ib902573996c69d1e77527cc7b2faf4e7fa5d3daf --- includes/Title.php | 14 +++++++++++--- includes/User.php | 11 ++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/includes/Title.php b/includes/Title.php index b97d36a416..f913859fdd 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -503,7 +503,7 @@ class Title { } $t = new Title(); - $t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki ); + $t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki, true ); if ( $t->secureAndSplit() ) { return $t; } else { @@ -747,12 +747,20 @@ class Title { * @param string $title The DB key form the title * @param string $fragment The link fragment (after the "#") * @param string $interwiki The interwiki prefix + * @param boolean $canoncialNamespace If true, use the canonical name for + * $ns instead of the localized version. * @return string The prefixed form of the title */ - public static function makeName( $ns, $title, $fragment = '', $interwiki = '' ) { + public static function makeName( $ns, $title, $fragment = '', $interwiki = '', + $canoncialNamespace = false + ) { global $wgContLang; - $namespace = $wgContLang->getNsText( $ns ); + if ( $canoncialNamespace ) { + $namespace = MWNamespace::getCanonicalName( $ns ); + } else { + $namespace = $wgContLang->getNsText( $ns ); + } $name = $namespace == '' ? $title : "$namespace:$title"; if ( strval( $interwiki ) != '' ) { $name = "$interwiki:$name"; diff --git a/includes/User.php b/includes/User.php index feaf3647b3..8fcdab26cf 100644 --- a/includes/User.php +++ b/includes/User.php @@ -565,15 +565,16 @@ class User implements IDBAccessObject { * @return int|null The corresponding user's ID, or null if user is nonexistent */ public static function idFromName( $name ) { + $nt = Title::makeTitleSafe( NS_USER, $name ); + if ( is_null( $nt ) ) { + // Illegal name + return null; + } + if ( isset( self::$idCacheByName[$name] ) ) { return self::$idCacheByName[$name]; } - // We don't want to call Title::makeTitleSafe yet, since that call path - // ends up needing the user language, which ends up trying to load the - // user object, which ends up back here (bug 54193). - $nt = Title::makeTitle( NS_USER, Title::capitalize( $name, NS_USER ) ); - $dbr = wfGetDB( DB_SLAVE ); $s = $dbr->selectRow( 'user', -- 2.20.1