From e7c55831de4c7903b63ca3efe413087984823457 Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Tue, 26 Apr 2022 09:34:51 -0700 Subject: [PATCH 1/2] hoist regexp literals in SourceMapDerToolPlugin --- lib/SourceMapDevToolPlugin.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/SourceMapDevToolPlugin.js b/lib/SourceMapDevToolPlugin.js index fc5a3dcf287..ce67713d6a4 100644 --- a/lib/SourceMapDevToolPlugin.js +++ b/lib/SourceMapDevToolPlugin.js @@ -47,13 +47,21 @@ const validate = createSchemaValidation( * @property {ItemCacheFacade} cacheItem cache item */ +const METACHARACTERS_REGEXP = /[-[\]\\/{}()*+?.^$|]/g; +const CONTENT_HASH_DETECT_REGEXP = /\[contenthash(:\w+)?\]/; +const CSS_AND_JS_MODULE_EXTENSIONS_REGEXP = /\.((c|m)?js|css)($|\?)/i; +const CSS_EXTENSION_DETECT_REGEXP = /\.css($|\?)/i; +const MAP_URL_COMMENT_REGEXP = /\[map\]/g; +const URL_COMMENT_REGEXP = /\[url\]/g; +const URL_FORMATTING_REGEXP = /^\n\/\/(.*)$/; + /** * Escapes regular expression metacharacters * @param {string} str String to quote * @returns {string} Escaped string */ const quoteMeta = str => { - return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); + return str.replace(METACHARACTERS_REGEXP, "\\$&"); }; /** @@ -152,7 +160,7 @@ class SourceMapDevToolPlugin { const fallbackModuleFilenameTemplate = this.fallbackModuleFilenameTemplate; const requestShortener = compiler.requestShortener; const options = this.options; - options.test = options.test || /\.((c|m)?js|css)($|\?)/i; + options.test = options.test || CSS_AND_JS_MODULE_EXTENSIONS_REGEXP; const matchObject = ModuleFilenameHelpers.matchObject.bind( undefined, @@ -409,7 +417,7 @@ class SourceMapDevToolPlugin { sourceMap.file = file; const usesContentHash = sourceMapFilename && - /\[contenthash(:\w+)?\]/.test(sourceMapFilename); + CONTENT_HASH_DETECT_REGEXP.test(sourceMapFilename); // If SourceMap and asset uses contenthash, avoid a circular dependency by hiding hash in `file` if (usesContentHash && task.assetInfo.contenthash) { @@ -430,11 +438,11 @@ class SourceMapDevToolPlugin { let currentSourceMappingURLComment = sourceMappingURLComment; if ( currentSourceMappingURLComment !== false && - /\.css($|\?)/i.test(file) + CSS_EXTENSION_DETECT_REGEXP.test(file) ) { currentSourceMappingURLComment = currentSourceMappingURLComment.replace( - /^\n\/\/(.*)$/, + URL_FORMATTING_REGEXP, "\n/*$1*/" ); } @@ -516,9 +524,9 @@ class SourceMapDevToolPlugin { const asset = new ConcatSource( new RawSource(source), currentSourceMappingURLComment - .replace(/\[map\]/g, () => sourceMapString) + .replace(MAP_URL_COMMENT_REGEXP, () => sourceMapString) .replace( - /\[url\]/g, + URL_COMMENT_REGEXP, () => `data:application/json;charset=utf-8;base64,${Buffer.from( sourceMapString, From 5e31761419bf9c1c4080d375da0ef4d85f684bcf Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Tue, 26 Apr 2022 13:46:26 -0700 Subject: [PATCH 2/2] reset state for stateful regexp --- lib/SourceMapDevToolPlugin.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/SourceMapDevToolPlugin.js b/lib/SourceMapDevToolPlugin.js index ce67713d6a4..49ebabc9b30 100644 --- a/lib/SourceMapDevToolPlugin.js +++ b/lib/SourceMapDevToolPlugin.js @@ -55,6 +55,17 @@ const MAP_URL_COMMENT_REGEXP = /\[map\]/g; const URL_COMMENT_REGEXP = /\[url\]/g; const URL_FORMATTING_REGEXP = /^\n\/\/(.*)$/; +/** + * Reset's .lastIndex of stateful Regular Expressions + * For when `test` or `exec` is called on them + * @param {RegExp} regexp Stateful Regular Expression to be reset + * @returns {void} + * + */ +const resetRegexpState = regexp => { + regexp.lastIndex = -1; +}; + /** * Escapes regular expression metacharacters * @param {string} str String to quote @@ -419,6 +430,8 @@ class SourceMapDevToolPlugin { sourceMapFilename && CONTENT_HASH_DETECT_REGEXP.test(sourceMapFilename); + resetRegexpState(CONTENT_HASH_DETECT_REGEXP); + // If SourceMap and asset uses contenthash, avoid a circular dependency by hiding hash in `file` if (usesContentHash && task.assetInfo.contenthash) { const contenthash = task.assetInfo.contenthash; @@ -436,9 +449,12 @@ class SourceMapDevToolPlugin { /** @type {string | false} */ let currentSourceMappingURLComment = sourceMappingURLComment; + let cssExtensionDetected = + CSS_EXTENSION_DETECT_REGEXP.test(file); + resetRegexpState(CSS_EXTENSION_DETECT_REGEXP); if ( currentSourceMappingURLComment !== false && - CSS_EXTENSION_DETECT_REGEXP.test(file) + cssExtensionDetected ) { currentSourceMappingURLComment = currentSourceMappingURLComment.replace(