Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling ES6 for ResourceLoader validation #5

Merged
merged 4 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"require": {
"mck89/peast": "^1.16"
},
"require-dev": {
"liquipedia/sqllint": "*",
"mediawiki/mediawiki-codesniffer": "*",
Expand Down
55 changes: 55 additions & 0 deletions src/ResourceLoader/ResourceLoaderArticlesModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@

use CSSJanus;
use Less_Parser;
use MediaWiki\MainConfigNames;
use MediaWiki\MediaWikiServices;
use MemoizedCallable;
use Peast\Peast;
use Peast\Syntax\Exception as PeastSyntaxException;
use ResourceLoader;
use ResourceLoaderContext;
use ResourceLoaderWikiModule;

class ResourceLoaderArticlesModule extends ResourceLoaderWikiModule {

private const USERJSPARSE_CACHE_VERSION = 3;

/**
* Get list of pages used by this module
*
Expand All @@ -39,6 +45,55 @@ protected function getPages( ResourceLoaderContext $context ) {
return $pages;
}

/**
* Override of the same function in order to support ES6 files
* Duplicate of https://gerrit.wikimedia.org/g/mediawiki/core/+/6fd9245f4ce47a77dc76f70994952cd6da2d1db7/includes/ResourceLoader/Module.php#1083
* Can be removed when moving to a MW version >= 1.41
* @param string $fileName
* @param string $contents
* @return string
*/
protected function validateScriptFile( $fileName, $contents ) {
if ( !$this->getConfig()->get( MainConfigNames::ResourceLoaderValidateJS ) ) {
return $contents;
}
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
// Cache potentially slow parsing of JavaScript code during the
// critical path. This happens lazily when responding to requests
// for modules=site, modules=user, and Gadgets.
$error = $cache->getWithSetCallback(
$cache->makeKey(
'resourceloader-userjsparse',
self::USERJSPARSE_CACHE_VERSION,
md5( $contents ),
$fileName
),
$cache::TTL_WEEK,
static function () use ( $contents, $fileName ) {
try {
Peast::ES2020( $contents )->parse();
} catch ( PeastSyntaxException $e ) {
return $e->getMessage() . " on line " . $e->getPosition()->getLine();
}
// Cache success as null
return null;
}
);
if ( $error ) {
// Send the error to the browser console client-side.
// By returning this as replacement for the actual script,
// we ensure user-provided scripts are safe to include in a batch
// request, without risk of a syntax error in this blob breaking
// the response itself.
return 'mw.log.error(' .
json_encode(
'Parse error: ' . $error . ' for file ' . $fileName
) .
');';
}
return $contents;
}

/**
* @param ResourceLoaderContext $context
* @return array
Expand Down