diff --git a/includes/resourceloader/ResourceLoaderSkinModule.php b/includes/resourceloader/ResourceLoaderSkinModule.php index dd831114424..de22650c832 100644 --- a/includes/resourceloader/ResourceLoaderSkinModule.php +++ b/includes/resourceloader/ResourceLoaderSkinModule.php @@ -246,9 +246,12 @@ class ResourceLoaderSkinModule extends ResourceLoaderLessVarFileModule { $listMode = false; foreach ( $features as $key => $enabled ) { - // TODO: Restore feature key validation (T271441) if ( is_string( $enabled ) ) { $listMode = true; + $key = $enabled; + } + if ( !isset( self::FEATURE_FILES[$key] ) ) { + throw new InvalidArgumentException( "Feature '$key' is not recognised" ); } } diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderSkinModuleTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderSkinModuleTest.php index 1f73fd8ed8b..00e3925f7ec 100644 --- a/tests/phpunit/includes/resourceloader/ResourceLoaderSkinModuleTest.php +++ b/tests/phpunit/includes/resourceloader/ResourceLoaderSkinModuleTest.php @@ -579,4 +579,38 @@ CSS array_values( $actual ) ); } + + public static function provideInvalidFeatures() { + yield 'listed unknown' => [ + [ 'logo', 'unknown' ], + ]; + + yield 'enabled unknown' => [ + [ + 'logo' => true, + 'toc' => false, + 'unknown' => true, + ], + ]; + + yield 'disbled unknown' => [ + [ + 'logo' => true, + 'toc' => false, + 'unknown' => false, + ], + ]; + } + + /** + * @covers ResourceLoaderSkinModule + * @dataProvider provideInvalidFeatures + */ + public function testConstructInvalidFeatures( array $features ) { + $this->expectException( InvalidArgumentException::class ); + $this->expectExceptionMessage( "Feature 'unknown' is not recognised" ); + $module = new ResourceLoaderSkinModule( [ + 'features' => $features, + ] ); + } }