Skip to content

Commit e1d5a35

Browse files
JakobJingleheimerBethGriggs
authored andcommitted
esm: improve validation of resolved URLs
PR-URL: #41446 Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Geoffrey Booth <[email protected]> Reviewed-By: Guy Bedford <[email protected]>
1 parent 38e4b11 commit e1d5a35

File tree

3 files changed

+14
-14
lines changed

3 files changed

+14
-14
lines changed

lib/internal/modules/esm/loader.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const {
2929
ERR_INVALID_RETURN_VALUE,
3030
ERR_UNKNOWN_MODULE_FORMAT
3131
} = require('internal/errors').codes;
32-
const { pathToFileURL, isURLInstance } = require('internal/url');
32+
const { pathToFileURL, isURLInstance, URL } = require('internal/url');
3333
const {
3434
isAnyArrayBuffer,
3535
isArrayBufferView,
@@ -558,7 +558,8 @@ class ESMLoader {
558558
format,
559559
);
560560
}
561-
if (typeof url !== 'string') {
561+
562+
if (typeof url !== 'string') { // non-strings can be coerced to a url string
562563
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
563564
'string',
564565
'loader resolve',
@@ -567,6 +568,8 @@ class ESMLoader {
567568
);
568569
}
569570

571+
new URL(url); // Intentionally trigger error if `url` is invalid
572+
570573
return {
571574
format,
572575
url,

test/es-module/test-esm-loader-invalid-url.mjs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ import assert from 'assert';
44

55
import('../fixtures/es-modules/test-esm-ok.mjs')
66
.then(assert.fail, (error) => {
7-
expectsError({
8-
code: 'ERR_INVALID_URL',
9-
message: 'Invalid URL'
10-
})(error);
11-
7+
expectsError({ code: 'ERR_INVALID_URL' })(error);
128
assert.strictEqual(error.input, '../fixtures/es-modules/test-esm-ok.mjs');
139
})
1410
.then(mustCall());

test/fixtures/es-module-loaders/hooks-custom.mjs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { pathToFileURL } from 'node:url';
12
import count from '../es-modules/stateful.mjs';
23

34

@@ -24,28 +25,28 @@ export function load(url, context, next) {
2425
format: 'module',
2526
});
2627

27-
if (url === 'esmHook/badReturnVal.mjs') return 'export function returnShouldBeObject() {}';
28+
if (url.endsWith('esmHook/badReturnVal.mjs')) return 'export function returnShouldBeObject() {}';
2829

29-
if (url === 'esmHook/badReturnFormatVal.mjs') return {
30+
if (url.endsWith('esmHook/badReturnFormatVal.mjs')) return {
3031
format: Array(0),
3132
source: '',
3233
}
33-
if (url === 'esmHook/unsupportedReturnFormatVal.mjs') return {
34+
if (url.endsWith('esmHook/unsupportedReturnFormatVal.mjs')) return {
3435
format: 'foo', // Not one of the allowable inputs: no translator named 'foo'
3536
source: '',
3637
}
3738

38-
if (url === 'esmHook/badReturnSourceVal.mjs') return {
39+
if (url.endsWith('esmHook/badReturnSourceVal.mjs')) return {
3940
format: 'module',
4041
source: Array(0),
4142
}
4243

43-
if (url === 'esmHook/preknownFormat.pre') return {
44+
if (url.endsWith('esmHook/preknownFormat.pre')) return {
4445
format: context.format,
4546
source: `const msg = 'hello world'; export default msg;`
4647
};
4748

48-
if (url === 'esmHook/virtual.mjs') return {
49+
if (url.endsWith('esmHook/virtual.mjs')) return {
4950
format: 'module',
5051
source: `export const message = 'Woohoo!'.toUpperCase();`,
5152
};
@@ -62,7 +63,7 @@ export function resolve(specifier, context, next) {
6263

6364
if (specifier.startsWith('esmHook')) return {
6465
format,
65-
url: specifier,
66+
url: pathToFileURL(specifier).href,
6667
importAssertions: context.importAssertions,
6768
};
6869

0 commit comments

Comments
 (0)