From a2eb55a2c9023de27c2d2018316a6f96ef121ab1 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 16 Sep 2022 09:03:41 +0000 Subject: [PATCH] lib: don't match `sourceMappingURL` in strings Prior to this change `sourceMappingURL` in string where being matched by the RegExp which caused sourcemaps not be loaded when using the `--enable-source-maps` flag. This commit changes the RegExp to match the last occurrence. Fixes: https://github.com/nodejs/node/issues/44654 PR-URL: https://github.com/nodejs/node/pull/44658 Reviewed-By: Chengzhong Wu Reviewed-By: Antoine du Hamel --- lib/internal/source_map/source_map_cache.js | 33 ++++++++++++------- .../typescript-sourcemapping_url_string.js | 4 +++ ...typescript-sourcemapping_url_string.js.map | 1 + .../source_map_sourcemapping_url_string.js | 13 ++++++++ .../source_map_sourcemapping_url_string.out | 3 ++ 5 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 test/fixtures/source-map/typescript-sourcemapping_url_string.js create mode 100644 test/fixtures/source-map/typescript-sourcemapping_url_string.js.map create mode 100644 test/message/source_map_sourcemapping_url_string.js create mode 100644 test/message/source_map_sourcemapping_url_string.out diff --git a/lib/internal/source_map/source_map_cache.js b/lib/internal/source_map/source_map_cache.js index 60852a4f439037..ee8de441ba9316 100644 --- a/lib/internal/source_map/source_map_cache.js +++ b/lib/internal/source_map/source_map_cache.js @@ -41,8 +41,8 @@ const esmSourceMapCache = new SafeMap(); // The generated sources is not mutable, so we can use a Map without memory concerns: const generatedSourceMapCache = new SafeMap(); const kLeadingProtocol = /^\w+:\/\//; -const kSourceMappingURLMagicComment = /\/[*/]#\s+sourceMappingURL=(?[^\s]+)/; -const kSourceURLMagicComment = /\/[*/]#\s+sourceURL=(?[^\s]+)/; +const kSourceMappingURLMagicComment = /\/[*/]#\s+sourceMappingURL=(?[^\s]+)/g; +const kSourceURLMagicComment = /\/[*/]#\s+sourceURL=(?[^\s]+)/g; const { fileURLToPath, pathToFileURL, URL } = require('internal/url'); let SourceMap; @@ -80,11 +80,14 @@ function setSourceMapsEnabled(val) { } function extractSourceURLMagicComment(content) { - const matchSourceURL = RegExpPrototypeExec( - kSourceURLMagicComment, - content - ); - if (matchSourceURL === null) { + let match; + let matchSourceURL; + // A while loop is used here to get the last occurrence of sourceURL. + // This is needed so that we don't match sourceURL in string literals. + while ((match = RegExpPrototypeExec(kSourceURLMagicComment, content))) { + matchSourceURL = match; + } + if (matchSourceURL == null) { return null; } let sourceURL = matchSourceURL.groups.sourceURL; @@ -104,13 +107,21 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance, isGeneratedSo debug(err); return; } - const match = RegExpPrototypeExec(kSourceMappingURLMagicComment, content); + + let match; + let lastMatch; + // A while loop is used here to get the last occurrence of sourceMappingURL. + // This is needed so that we don't match sourceMappingURL in string literals. + while ((match = RegExpPrototypeExec(kSourceMappingURLMagicComment, content))) { + lastMatch = match; + } + if (sourceURL === undefined) { sourceURL = extractSourceURLMagicComment(content); } - if (match) { - const data = dataFromUrl(filename, match.groups.sourceMappingURL); - const url = data ? null : match.groups.sourceMappingURL; + if (lastMatch) { + const data = dataFromUrl(filename, lastMatch.groups.sourceMappingURL); + const url = data ? null : lastMatch.groups.sourceMappingURL; if (cjsModuleInstance) { cjsSourceMapCache.set(cjsModuleInstance, { filename, diff --git a/test/fixtures/source-map/typescript-sourcemapping_url_string.js b/test/fixtures/source-map/typescript-sourcemapping_url_string.js new file mode 100644 index 00000000000000..1ac4e985843dc2 --- /dev/null +++ b/test/fixtures/source-map/typescript-sourcemapping_url_string.js @@ -0,0 +1,4 @@ +"use strict"; +const content = '//# sourceMappingURL='; +throw new Error('an exception.'); +//# sourceMappingURL=typescript-sourcemapping_url_string.js.map diff --git a/test/fixtures/source-map/typescript-sourcemapping_url_string.js.map b/test/fixtures/source-map/typescript-sourcemapping_url_string.js.map new file mode 100644 index 00000000000000..cbb2d46f169df2 --- /dev/null +++ b/test/fixtures/source-map/typescript-sourcemapping_url_string.js.map @@ -0,0 +1 @@ +{"version":3,"file":"typescript-sourcemapping_url_string.js","sourceRoot":"","sources":["typescript-sourcemapping_url_string.ts"],"names":[],"mappings":";AAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC;AAExC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC"} diff --git a/test/message/source_map_sourcemapping_url_string.js b/test/message/source_map_sourcemapping_url_string.js new file mode 100644 index 00000000000000..254d18bd080e53 --- /dev/null +++ b/test/message/source_map_sourcemapping_url_string.js @@ -0,0 +1,13 @@ +// Flags: --enable-source-maps + +'use strict'; +require('../common'); +Error.stackTraceLimit = 2; + +try { + require('../fixtures/source-map/typescript-sourcemapping_url_string'); +} catch (err) { + setTimeout(() => { + console.info(err); + }, 10); +} diff --git a/test/message/source_map_sourcemapping_url_string.out b/test/message/source_map_sourcemapping_url_string.out new file mode 100644 index 00000000000000..3d0b6e15eb6c7a --- /dev/null +++ b/test/message/source_map_sourcemapping_url_string.out @@ -0,0 +1,3 @@ +Error: an exception. + at *typescript-sourcemapping_url_string.ts:3:7* + at Module._compile (node:internal/modules/cjs/loader:*)