During special page transclusion, save and restore context's WikiPage too

Setting the Title by calling setTitle clears the WikiPage, and the
next time getWikiPage() is called, it will be lazy-initialized to a
different instance of WikiPage.

This is mostly okay (the behavior has been like this for years and no
one noticed any problems), but it turns out that some extensions
(ConfirmEdit) use custom properties on the WikiPage object to pass
data between different hooks, which are lost when it's re-initialized.

Bug: T207065
Change-Id: I2881895f337bcfb1f86d5fc5a994fa9b0dcc768a
This commit is contained in:
Bartosz Dziewoński 2018-10-18 01:23:27 +02:00
parent c44bba66c9
commit 5f7002b907
2 changed files with 25 additions and 0 deletions

View file

@ -606,6 +606,9 @@ class SpecialPageFactory {
'user' => $main->getUser(),
'language' => $main->getLanguage(),
];
if ( $main->canUseWikiPage() ) {
$ctx['wikipage'] = $main->getWikiPage();
}
// Override
$wgTitle = $title;
@ -633,6 +636,9 @@ class SpecialPageFactory {
$main->setRequest( $ctx['request'] );
$main->setUser( $ctx['user'] );
$main->setLanguage( $ctx['language'] );
if ( isset( $ctx['wikipage'] ) ) {
$main->setWikiPage( $ctx['wikipage'] );
}
return $ret;
}

View file

@ -46,6 +46,25 @@ class ExtraParserTest extends MediaWikiTestCase {
$this->parser->parse( $longLine, $title, $options )->getText( [ 'unwrap' => true ] ) );
}
/**
* @covers Parser::braceSubstitution
* @covers SpecialPageFactory::capturePath
*/
public function testSpecialPageTransclusionRestoresGlobalState() {
$text = "{{Special:ApiHelp/help}}";
$title = Title::newFromText( 'testSpecialPageTransclusionRestoresGlobalState' );
$options = ParserOptions::newFromUser( new User() );
RequestContext::getMain()->setTitle( $title );
RequestContext::getMain()->getWikiPage()->CustomTestProp = true;
$parsed = $this->parser->parse( $text, $title, $options )->getText();
$this->assertContains( 'apihelp-header', $parsed );
// Verify that this property wasn't wiped out by the parse
$this->assertTrue( RequestContext::getMain()->getWikiPage()->CustomTestProp );
}
/**
* Test the parser entry points
* @covers Parser::parse