From ed970eb5cc61c054d84d70ceab4e179206964f41 Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Sat, 8 Jan 2022 18:23:13 +0100 Subject: [PATCH 1/2] esm: improve validation of resolved URLs --- lib/internal/modules/esm/loader.js | 12 +++--------- test/es-module/test-esm-loader-invalid-url.mjs | 6 +----- test/fixtures/es-module-loaders/hooks-custom.mjs | 15 ++++++++------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 91f570297be341..2ed27c9f5f0165 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -29,7 +29,7 @@ const { ERR_INVALID_RETURN_VALUE, ERR_UNKNOWN_MODULE_FORMAT } = require('internal/errors').codes; -const { pathToFileURL, isURLInstance } = require('internal/url'); +const { pathToFileURL, isURLInstance, URL } = require('internal/url'); const { isAnyArrayBuffer, isArrayBufferView, @@ -558,14 +558,8 @@ class ESMLoader { format, ); } - if (typeof url !== 'string') { - throw new ERR_INVALID_RETURN_PROPERTY_VALUE( - 'string', - 'loader resolve', - 'url', - url, - ); - } + + new URL(url); // Intentionally trigger error if `url` is invalid return { format, diff --git a/test/es-module/test-esm-loader-invalid-url.mjs b/test/es-module/test-esm-loader-invalid-url.mjs index 7dce946da2c3c3..6294e57404c8bb 100644 --- a/test/es-module/test-esm-loader-invalid-url.mjs +++ b/test/es-module/test-esm-loader-invalid-url.mjs @@ -4,11 +4,7 @@ import assert from 'assert'; import('../fixtures/es-modules/test-esm-ok.mjs') .then(assert.fail, (error) => { - expectsError({ - code: 'ERR_INVALID_URL', - message: 'Invalid URL' - })(error); - + expectsError({ code: 'ERR_INVALID_URL' })(error); assert.strictEqual(error.input, '../fixtures/es-modules/test-esm-ok.mjs'); }) .then(mustCall()); diff --git a/test/fixtures/es-module-loaders/hooks-custom.mjs b/test/fixtures/es-module-loaders/hooks-custom.mjs index cd9d5020ad3234..5173b97387905a 100644 --- a/test/fixtures/es-module-loaders/hooks-custom.mjs +++ b/test/fixtures/es-module-loaders/hooks-custom.mjs @@ -1,3 +1,4 @@ +import { pathToFileURL } from 'node:url'; import count from '../es-modules/stateful.mjs'; @@ -24,28 +25,28 @@ export function load(url, context, next) { format: 'module', }); - if (url === 'esmHook/badReturnVal.mjs') return 'export function returnShouldBeObject() {}'; + if (url.endsWith('esmHook/badReturnVal.mjs')) return 'export function returnShouldBeObject() {}'; - if (url === 'esmHook/badReturnFormatVal.mjs') return { + if (url.endsWith('esmHook/badReturnFormatVal.mjs')) return { format: Array(0), source: '', } - if (url === 'esmHook/unsupportedReturnFormatVal.mjs') return { + if (url.endsWith('esmHook/unsupportedReturnFormatVal.mjs')) return { format: 'foo', // Not one of the allowable inputs: no translator named 'foo' source: '', } - if (url === 'esmHook/badReturnSourceVal.mjs') return { + if (url.endsWith('esmHook/badReturnSourceVal.mjs')) return { format: 'module', source: Array(0), } - if (url === 'esmHook/preknownFormat.pre') return { + if (url.endsWith('esmHook/preknownFormat.pre')) return { format: context.format, source: `const msg = 'hello world'; export default msg;` }; - if (url === 'esmHook/virtual.mjs') return { + if (url.endsWith('esmHook/virtual.mjs')) return { format: 'module', source: `export const message = 'Woohoo!'.toUpperCase();`, }; @@ -62,7 +63,7 @@ export function resolve(specifier, context, next) { if (specifier.startsWith('esmHook')) return { format, - url: specifier, + url: pathToFileURL(specifier).href, importAssertions: context.importAssertions, }; From b4fb1aebe84f350534956edee7dab05d7a1d25a7 Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Mon, 10 Jan 2022 23:04:21 +0100 Subject: [PATCH 2/2] fixup: restore "is a string" check on `url` --- lib/internal/modules/esm/loader.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 2ed27c9f5f0165..1707db8b1857fa 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -559,6 +559,15 @@ class ESMLoader { ); } + if (typeof url !== 'string') { // non-strings can be coerced to a url string + throw new ERR_INVALID_RETURN_PROPERTY_VALUE( + 'string', + 'loader resolve', + 'url', + url, + ); + } + new URL(url); // Intentionally trigger error if `url` is invalid return {