From: Bartosz DziewoƄski Date: Wed, 17 Oct 2018 23:23:27 +0000 (+0200) Subject: During special page transclusion, save and restore context's WikiPage too X-Git-Tag: 1.34.0-rc.0~3724^2 X-Git-Url: http://git.heureux-cyclage.org/?a=commitdiff_plain;h=5f7002b907ac3eec2262fb590a914196fd5a780d;p=lhc%2Fweb%2Fwiklou.git 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 --- diff --git a/includes/specialpage/SpecialPageFactory.php b/includes/specialpage/SpecialPageFactory.php index 013ceb24e5..b91273a694 100644 --- a/includes/specialpage/SpecialPageFactory.php +++ b/includes/specialpage/SpecialPageFactory.php @@ -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; } diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php index 7ce4d1efc6..fc317b7198 100644 --- a/tests/phpunit/includes/ExtraParserTest.php +++ b/tests/phpunit/includes/ExtraParserTest.php @@ -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