From: daniel Date: Fri, 9 Jun 2017 16:39:33 +0000 (+0200) Subject: Make Titles with an unknown namespace ID refer to Special:Badtitle. X-Git-Tag: 1.31.0-rc.0~2987 X-Git-Url: http://git.cyclocoop.org/?a=commitdiff_plain;h=fbc144965315cb1360500ef08ae9f4af15e76c43;p=lhc%2Fweb%2Fwiklou.git Make Titles with an unknown namespace ID refer to Special:Badtitle. Without this patch, Title::getPrefixedText() would return ":Foo" if the namespace was unknown, potentially creating a misleading link to the main namespace. With this change, getPrefixedText() will return something like "Special:Badtitle/NS12345:Foo". Note that round trip behavior is broken either way. Bug: T165149 Change-Id: I0d491a2b58ff45f207f83ee62ca6e7e6ffbf790a --- diff --git a/includes/Title.php b/includes/Title.php index a8cfad8748..c9f09f79e2 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -1419,13 +1419,22 @@ class Title implements LinkTarget { * @return string The prefixed text */ private function prefix( $name ) { + global $wgContLang; + $p = ''; if ( $this->isExternal() ) { $p = $this->mInterwiki . ':'; } if ( 0 != $this->mNamespace ) { - $p .= $this->getNsText() . ':'; + $nsText = $this->getNsText(); + + if ( $nsText === false ) { + // See T165149. Awkward, but better than erroneously linking to the main namespace. + $nsText = $wgContLang->getNsText( NS_SPECIAL ) . ":Badtitle/NS{$this->mNamespace}"; + } + + $p .= $nsText . ':'; } return $p . $name; } diff --git a/tests/phpunit/includes/TitleTest.php b/tests/phpunit/includes/TitleTest.php index 238b65f429..6c4499948d 100644 --- a/tests/phpunit/includes/TitleTest.php +++ b/tests/phpunit/includes/TitleTest.php @@ -716,28 +716,33 @@ class TitleTest extends MediaWikiTestCase { return [ // ns = 0 [ - Title::makeTitle( NS_MAIN, 'Foobar' ), - 'Foobar' + Title::makeTitle( NS_MAIN, 'Foo bar' ), + 'Foo bar' ], // ns = 2 [ - Title::makeTitle( NS_USER, 'Foobar' ), - 'User:Foobar' + Title::makeTitle( NS_USER, 'Foo bar' ), + 'User:Foo bar' + ], + // ns = 3 + [ + Title::makeTitle( NS_USER_TALK, 'Foo bar' ), + 'User talk:Foo bar' ], // fragment not included [ - Title::makeTitle( NS_MAIN, 'Foobar', 'fragment' ), - 'Foobar' + Title::makeTitle( NS_MAIN, 'Foo bar', 'fragment' ), + 'Foo bar' ], // ns = -2 [ - Title::makeTitle( NS_MEDIA, 'Foobar' ), - 'Media:Foobar' + Title::makeTitle( NS_MEDIA, 'Foo bar' ), + 'Media:Foo bar' ], // non-existent namespace [ - Title::makeTitle( 100000, 'Foobar' ), - ':Foobar' + Title::makeTitle( 100777, 'Foo bar' ), + 'Special:Badtitle/NS100777:Foo bar' ], ]; } @@ -749,4 +754,47 @@ class TitleTest extends MediaWikiTestCase { public function testGetPrefixedText( Title $title, $expected ) { $this->assertEquals( $expected, $title->getPrefixedText() ); } + + public function provideGetPrefixedDBKey() { + return [ + // ns = 0 + [ + Title::makeTitle( NS_MAIN, 'Foo_bar' ), + 'Foo_bar' + ], + // ns = 2 + [ + Title::makeTitle( NS_USER, 'Foo_bar' ), + 'User:Foo_bar' + ], + // ns = 3 + [ + Title::makeTitle( NS_USER_TALK, 'Foo_bar' ), + 'User_talk:Foo_bar' + ], + // fragment not included + [ + Title::makeTitle( NS_MAIN, 'Foo_bar', 'fragment' ), + 'Foo_bar' + ], + // ns = -2 + [ + Title::makeTitle( NS_MEDIA, 'Foo_bar' ), + 'Media:Foo_bar' + ], + // non-existent namespace + [ + Title::makeTitle( 100777, 'Foo_bar' ), + 'Special:Badtitle/NS100777:Foo_bar' + ], + ]; + } + + /** + * @covers Title::getPrefixedDBKey + * @dataProvider provideGetPrefixedDBKey + */ + public function testGetPrefixedDBKey( Title $title, $expected ) { + $this->assertEquals( $expected, $title->getPrefixedDBkey() ); + } }