title: Convert binary regexp to use Unicode code points
[lhc/web/wiklou.git] / includes / title / MediaWikiTitleCodec.php
index f6a4c06..7af0c1e 100644 (file)
@@ -56,20 +56,35 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
         */
        protected $interwikiLookup;
 
+       /**
+        * @var NamespaceInfo
+        */
+       protected $nsInfo;
+
        /**
         * @param Language $language The language object to use for localizing namespace names.
         * @param GenderCache $genderCache The gender cache for generating gendered namespace names
         * @param string[]|string $localInterwikis
         * @param InterwikiLookup|null $interwikiLookup
+        * @param NamespaceInfo|null $nsInfo
         */
        public function __construct( Language $language, GenderCache $genderCache,
-               $localInterwikis = [], $interwikiLookup = null
+               $localInterwikis = [], InterwikiLookup $interwikiLookup = null,
+               NamespaceInfo $nsInfo = null
        ) {
+               if ( !$interwikiLookup ) {
+                       wfDeprecated( __METHOD__ . ' with no InterwikiLookup argument', '1.34' );
+                       $interwikiLookup = MediaWikiServices::getInstance()->getInterwikiLookup();
+               }
+               if ( !$nsInfo ) {
+                       wfDeprecated( __METHOD__ . ' with no NamespaceInfo argument', '1.34' );
+                       $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
+               }
                $this->language = $language;
                $this->genderCache = $genderCache;
                $this->localInterwikis = (array)$localInterwikis;
-               $this->interwikiLookup = $interwikiLookup ?:
-                       MediaWikiServices::getInstance()->getInterwikiLookup();
+               $this->interwikiLookup = $interwikiLookup;
+               $this->nsInfo = $nsInfo;
        }
 
        /**
@@ -83,7 +98,7 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
         */
        public function getNamespaceName( $namespace, $text ) {
                if ( $this->language->needsGenderDistinction() &&
-                       MWNamespace::hasGenderDistinction( $namespace )
+                       $this->nsInfo->hasGenderDistinction( $namespace )
                ) {
                        // NOTE: we are assuming here that the title text is a user name!
                        $gender = $this->genderCache->getGenderOf( $text, __METHOD__ );
@@ -149,13 +164,17 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
         * @return TitleValue
         */
        public function parseTitle( $text, $defaultNamespace = NS_MAIN ) {
+               // Convert things like é ā or 〗 into normalized (T16952) text
+               $filteredText = Sanitizer::decodeCharReferencesAndNormalize( $text );
+
                // NOTE: this is an ugly cludge that allows this class to share the
                // code for parsing with the old Title class. The parser code should
                // be refactored to avoid this.
-               $parts = $this->splitTitleString( $text, $defaultNamespace );
+               $parts = $this->splitTitleString( $filteredText, $defaultNamespace );
 
-               // Relative fragment links are not supported by TitleValue
-               if ( $parts['dbkey'] === '' ) {
+               // Fragment-only is okay, but only with no namespace
+               if ( $parts['dbkey'] === '' &&
+               ( $parts['fragment'] === '' || $parts['namespace'] !== NS_MAIN ) ) {
                        throw new MalformedTitleException( 'title-invalid-empty', $text );
                }
 
@@ -265,7 +284,7 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
                # Strip Unicode bidi override characters.
                # Sometimes they slip into cut-n-pasted page titles, where the
                # override chars get included in list displays.
-               $dbkey = preg_replace( '/\xE2\x80[\x8E\x8F\xAA-\xAE]/S', '', $dbkey );
+               $dbkey = preg_replace( '/[\x{200E}\x{200F}\x{202A}-\x{202E}]+/u', '', $dbkey );
 
                # Clean up whitespace
                # Note: use of the /u option on preg_replace here will cause
@@ -325,7 +344,7 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
 
                                        # Redundant interwiki prefix to the local wiki
                                        foreach ( $this->localInterwikis as $localIW ) {
-                                               if ( 0 == strcasecmp( $parts['interwiki'], $localIW ) ) {
+                                               if ( strcasecmp( $parts['interwiki'], $localIW ) == 0 ) {
                                                        if ( $dbkey == '' ) {
                                                                # Empty self-links should point to the Main Page, to ensure
                                                                # compatibility with cross-wiki transclusions and the like.
@@ -363,7 +382,7 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
                } while ( true );
 
                $fragment = strstr( $dbkey, '#' );
-               if ( false !== $fragment ) {
+               if ( $fragment !== false ) {
                        $parts['fragment'] = str_replace( '_', ' ', substr( $fragment, 1 ) );
                        $dbkey = substr( $dbkey, 0, strlen( $dbkey ) - strlen( $fragment ) );
                        # remove whitespace again: prevents "Foo_bar_#"
@@ -421,10 +440,8 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
 
                # Can't make a link to a namespace alone... "empty" local links can only be
                # self-links with a fragment identifier.
-               if ( $dbkey == '' && $parts['interwiki'] === '' ) {
-                       if ( $parts['namespace'] != NS_MAIN ) {
-                               throw new MalformedTitleException( 'title-invalid-empty', $text );
-                       }
+               if ( $dbkey == '' && $parts['interwiki'] === '' && $parts['namespace'] != NS_MAIN ) {
+                       throw new MalformedTitleException( 'title-invalid-empty', $text );
                }
 
                // Allow IPv6 usernames to start with '::' by canonicalizing IPv6 titles.
@@ -438,7 +455,7 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
                }
 
                // Any remaining initial :s are illegal.
-               if ( $dbkey !== '' && ':' == $dbkey[0] ) {
+               if ( $dbkey !== '' && $dbkey[0] == ':' ) {
                        throw new MalformedTitleException( 'title-invalid-leading-colon', $text );
                }