Files
node/test/parallel/test-webworker-importscripts-conversion.js
Filip Skokan 5643755589 worker: convert importScripts arguments first
Web IDL converts every argument before entering the method algorithm.
Perform all USVString conversions before rejecting module workers or
parsing URLs, so later conversions can throw or revoke blob URLs first.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Assisted-by: Codex
PR-URL: https://github.com/nodejs/node/pull/66354
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
2026-09-29 17:19:26 +00:00

68 lines
1.9 KiB
JavaScript

// Flags: --experimental-web-worker
'use strict';
const common = require('../common');
const assert = require('node:assert');
for (const type of ['classic', 'module']) {
const source = `
const results = [];
const conversions = [];
const sentinel = new Error('conversion');
try {
importScripts('https://[', {
toString() { conversions.push('converted'); throw sentinel; }
});
} catch (error) {
results.push([conversions, error === sentinel]);
}
const order = [];
try {
importScripts(
{ toString() { order.push(1); return 'https://['; } },
{ toString() { order.push(2); return 'data:text/javascript,'; } }
);
} catch (error) {
results.push([order, error.name]);
}
postMessage(results);
`;
const worker = new Worker(`data:text/javascript,${encodeURIComponent(source)}`, { type });
worker.onerror = common.mustNotCall('worker failed');
worker.onmessage = common.mustCall(({ data }) => {
worker.terminate();
assert.deepStrictEqual(data, [
[['converted'], true],
[[1, 2], type === 'module' ? 'TypeError' : 'SyntaxError'],
]);
});
}
if (common.hasCrypto) {
// URL parsing must capture blob entries after all arguments are converted.
const source = `
self.ran = false;
const url = URL.createObjectURL(new Blob(['self.ran = true'], {
type: 'text/javascript'
}));
let errorName;
try {
importScripts(url, {
toString() {
URL.revokeObjectURL(url);
return 'data:text/javascript,';
}
});
} catch (error) {
errorName = error.name;
}
postMessage([self.ran, errorName]);
`;
const worker = new Worker(`data:text/javascript,${encodeURIComponent(source)}`);
worker.onerror = common.mustNotCall('worker failed');
worker.onmessage = common.mustCall(({ data }) => {
worker.terminate();
assert.deepStrictEqual(data, [false, 'NetworkError']);
});
}