Skip to content

Commit

Permalink
esm: improve validation of resolved URLs
Browse files Browse the repository at this point in the history
PR-URL: #41446
Reviewed-By: Bradley Farias <[email protected]>
Reviewed-By: Geoffrey Booth <[email protected]>
Reviewed-By: Guy Bedford <[email protected]>
  • Loading branch information
JakobJingleheimer authored and danielleadams committed Feb 26, 2022
1 parent f21df19 commit ea84c89
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 14 deletions.
7 changes: 5 additions & 2 deletions lib/internal/modules/esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -558,7 +558,8 @@ class ESMLoader {
format,
);
}
if (typeof url !== 'string') {

if (typeof url !== 'string') { // non-strings can be coerced to a url string
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
'string',
'loader resolve',
Expand All @@ -567,6 +568,8 @@ class ESMLoader {
);
}

new URL(url); // Intentionally trigger error if `url` is invalid

return {
format,
url,
Expand Down
6 changes: 1 addition & 5 deletions test/es-module/test-esm-loader-invalid-url.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
15 changes: 8 additions & 7 deletions test/fixtures/es-module-loaders/hooks-custom.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { pathToFileURL } from 'node:url';
import count from '../es-modules/stateful.mjs';


Expand All @@ -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();`,
};
Expand All @@ -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,
};

Expand Down

0 comments on commit ea84c89

Please sign in to comment.