From: jenkins-bot Date: Sat, 19 May 2018 21:26:35 +0000 (+0000) Subject: Merge "Re-enable Generic.Files.OneObjectStructurePerFile sniff" X-Git-Tag: 1.34.0-rc.0~5371 X-Git-Url: https://git.cyclocoop.org/%7B%24admin_url%7Dmembres/modifier.php?a=commitdiff_plain;h=d20882ff0525ab7350aef97b0741dbc28e0218d0;hp=2331d9742a5edd4cf0dab9677f53f1945511f3f9;p=lhc%2Fweb%2Fwiklou.git Merge "Re-enable Generic.Files.OneObjectStructurePerFile sniff" --- diff --git a/includes/OutputPage.php b/includes/OutputPage.php index dd1a4db0b7..c7028db7d3 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -2443,7 +2443,7 @@ class OutputPage extends ContextSource { if ( $this->mArticleBodyOnly ) { echo $this->mBodytext; } else { - // Enable safe mode if requested + // Enable safe mode if requested (T152169) if ( $this->getRequest()->getBool( 'safemode' ) ) { $this->disallowUserJs(); } @@ -2862,6 +2862,16 @@ class OutputPage extends ContextSource { $rlClient = new ResourceLoaderClientHtml( $context, [ 'target' => $this->getTarget(), 'nonce' => $this->getCSPNonce(), + // When 'safemode', disallowUserJs(), or reduceAllowedModules() is used + // to only restrict modules to ORIGIN_CORE (ie. disallow ORIGIN_USER), the list of + // modules enqueud for loading on this page is filtered to just those. + // However, to make sure we also apply the restriction to dynamic dependencies and + // lazy-loaded modules at run-time on the client-side, pass 'safemode' down to the + // StartupModule so that the client-side registry will not contain any restricted + // modules either. (T152169, T185303) + 'safemode' => ( $this->getAllowedModules( ResourceLoaderModule::TYPE_COMBINED ) + <= ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL + ) ? '1' : null, ] ); $rlClient->setConfig( $this->getJSVars() ); $rlClient->setModules( $this->getModules( /*filter*/ true ) ); diff --git a/includes/resourceloader/ResourceLoaderClientHtml.php b/includes/resourceloader/ResourceLoaderClientHtml.php index 479a263136..3ba63cf04a 100644 --- a/includes/resourceloader/ResourceLoaderClientHtml.php +++ b/includes/resourceloader/ResourceLoaderClientHtml.php @@ -57,7 +57,8 @@ class ResourceLoaderClientHtml { /** * @param ResourceLoaderContext $context * @param array $options [optional] Array of options - * - 'target': Custom parameter passed to StartupModule. + * - 'target': Parameter for modules=startup request, see ResourceLoaderStartUpModule. + * - 'safemode': Parameter for modules=startup request, see ResourceLoaderStartUpModule. * - 'nonce': From OutputPage::getCSPNonce(). */ public function __construct( ResourceLoaderContext $context, array $options = [] ) { @@ -65,6 +66,7 @@ class ResourceLoaderClientHtml { $this->resourceLoader = $context->getResourceLoader(); $this->options = $options + [ 'target' => null, + 'safemode' => null, 'nonce' => null, ]; } @@ -344,9 +346,12 @@ class ResourceLoaderClientHtml { // Async scripts. Once the startup is loaded, inline RLQ scripts will run. // Pass-through a custom 'target' from OutputPage (T143066). - $startupQuery = $this->options['target'] !== null - ? [ 'target' => (string)$this->options['target'] ] - : []; + $startupQuery = []; + foreach ( [ 'target', 'safemode' ] as $param ) { + if ( $this->options[$param] !== null ) { + $startupQuery[$param] = (string)$this->options[$param]; + } + } $chunks[] = $this->getLoad( 'startup', ResourceLoaderModule::TYPE_SCRIPTS, diff --git a/includes/resourceloader/ResourceLoaderModule.php b/includes/resourceloader/ResourceLoaderModule.php index 7351cb3ef5..a0a4e5865a 100644 --- a/includes/resourceloader/ResourceLoaderModule.php +++ b/includes/resourceloader/ResourceLoaderModule.php @@ -318,9 +318,9 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface { } /** - * Get the origin of this module. Should only be overridden for foreign modules. + * Get the source of this module. Should only be overridden for foreign modules. * - * @return string Origin name, 'local' for local modules + * @return string Source name, 'local' for local modules */ public function getSource() { // Stub, override expected diff --git a/includes/resourceloader/ResourceLoaderStartUpModule.php b/includes/resourceloader/ResourceLoaderStartUpModule.php index 2e3c6fc161..6b92f773b6 100644 --- a/includes/resourceloader/ResourceLoaderStartUpModule.php +++ b/includes/resourceloader/ResourceLoaderStartUpModule.php @@ -29,9 +29,13 @@ * the ability to vary based extra query parameters, in addition to those * from ResourceLoaderContext: * - * - target: Only register modules in the client allowed within this target. + * - target: Only register modules in the client intended for this target. * Default: "desktop". * See also: OutputPage::setTarget(), ResourceLoaderModule::getTargets(). + * + * - safemode: Only register modules that have ORIGIN_CORE as their origin. + * This effectively disables ORIGIN_USER modules. (T185303) + * See also: OutputPage::disallowUserJs() */ class ResourceLoaderStartUpModule extends ResourceLoaderModule { @@ -208,6 +212,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { // Future developers: Use WebRequest::getRawVal() instead getVal(). // The getVal() method performs slow Language+UTF logic. (f303bb9360) $target = $context->getRequest()->getRawVal( 'target', 'desktop' ); + $safemode = $context->getRequest()->getRawVal( 'safemode' ) === '1'; // Bypass target filter if this request is Special:JavaScriptTest. // To prevent misuse in production, this is only allowed if testing is enabled server-side. $byPassTargetFilter = $this->getConfig()->get( 'EnableJavaScriptTest' ) && $target === 'test'; @@ -220,7 +225,10 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { foreach ( $resourceLoader->getModuleNames() as $name ) { $module = $resourceLoader->getModule( $name ); $moduleTargets = $module->getTargets(); - if ( !$byPassTargetFilter && !in_array( $target, $moduleTargets ) ) { + if ( + ( !$byPassTargetFilter && !in_array( $target, $moduleTargets ) ) + || ( $safemode && $module->getOrigin() > ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL ) + ) { continue; } diff --git a/tests/phpunit/ResourceLoaderTestCase.php b/tests/phpunit/ResourceLoaderTestCase.php index d5c14a2558..f0c78ecea0 100644 --- a/tests/phpunit/ResourceLoaderTestCase.php +++ b/tests/phpunit/ResourceLoaderTestCase.php @@ -31,12 +31,14 @@ abstract class ResourceLoaderTestCase extends MediaWikiTestCase { 'skin' => 'vector', 'modules' => 'startup', 'only' => 'scripts', + 'safemode' => null, ]; $resourceLoader = $rl ?: new ResourceLoader(); $request = new FauxRequest( [ 'lang' => $options['lang'], 'modules' => $options['modules'], 'only' => $options['only'], + 'safemode' => $options['safemode'], 'skin' => $options['skin'], 'target' => 'phpunit', ] ); diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php index 5b5c484b42..9b03c5ccdd 100644 --- a/tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php +++ b/tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php @@ -258,6 +258,25 @@ Deprecation message.' ] $this->assertEquals( $expected, $client->getHeadHtml() ); } + /** + * Confirm that 'safemode' is passed down to startup. + * + * @covers ResourceLoaderClientHtml::getHeadHtml + */ + public function testGetHeadHtmlWithSafemode() { + $client = new ResourceLoaderClientHtml( + self::makeContext(), + [ 'safemode' => '1' ] + ); + + // phpcs:disable Generic.Files.LineLength + $expected = '' . "\n" + . ''; + // phpcs:enable + + $this->assertEquals( $expected, $client->getHeadHtml() ); + } + /** * Confirm that a null 'target' is the same as no target. * diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php index 564f50bc35..ca4fb34139 100644 --- a/tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php +++ b/tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php @@ -162,6 +162,75 @@ mw.loader.register( [ "test.blank", "{blankVer}" ] +] );' + ] ], + [ [ + 'msg' => 'Safemode disabled (default; register all modules)', + 'modules' => [ + // Default origin: ORIGIN_CORE_SITEWIDE + 'test.blank' => new ResourceLoaderTestModule(), + 'test.core-generated' => new ResourceLoaderTestModule( [ + 'origin' => ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL + ] ), + 'test.sitewide' => new ResourceLoaderTestModule( [ + 'origin' => ResourceLoaderModule::ORIGIN_USER_SITEWIDE + ] ), + 'test.user' => new ResourceLoaderTestModule( [ + 'origin' => ResourceLoaderModule::ORIGIN_USER_INDIVIDUAL + ] ), + ], + 'out' => ' +mw.loader.addSource( { + "local": "/w/load.php" +} ); +mw.loader.register( [ + [ + "test.blank", + "{blankVer}" + ], + [ + "test.core-generated", + "{blankVer}" + ], + [ + "test.sitewide", + "{blankVer}" + ], + [ + "test.user", + "{blankVer}" + ] +] );' + ] ], + [ [ + 'msg' => 'Safemode enabled (filter modules with user/site origin)', + 'extraQuery' => [ 'safemode' => '1' ], + 'modules' => [ + // Default origin: ORIGIN_CORE_SITEWIDE + 'test.blank' => new ResourceLoaderTestModule(), + 'test.core-generated' => new ResourceLoaderTestModule( [ + 'origin' => ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL + ] ), + 'test.sitewide' => new ResourceLoaderTestModule( [ + 'origin' => ResourceLoaderModule::ORIGIN_USER_SITEWIDE + ] ), + 'test.user' => new ResourceLoaderTestModule( [ + 'origin' => ResourceLoaderModule::ORIGIN_USER_INDIVIDUAL + ] ), + ], + 'out' => ' +mw.loader.addSource( { + "local": "/w/load.php" +} ); +mw.loader.register( [ + [ + "test.blank", + "{blankVer}" + ], + [ + "test.core-generated", + "{blankVer}" + ] ] );' ] ], [ [ @@ -394,7 +463,8 @@ mw.loader.register( [ $this->setMwGlobals( 'wgResourceLoaderSources', $case['sources'] ); } - $context = $this->getResourceLoaderContext(); + $extraQuery = isset( $case['extraQuery'] ) ? $case['extraQuery'] : []; + $context = $this->getResourceLoaderContext( $extraQuery ); $rl = $context->getResourceLoader(); $rl->register( $case['modules'] ); $module = new ResourceLoaderStartUpModule();