diff --git a/benchmark/esm/get-data-protocol-format.js b/benchmark/esm/get-data-protocol-format.js new file mode 100644 index 00000000000000..35e54a7700354a --- /dev/null +++ b/benchmark/esm/get-data-protocol-format.js @@ -0,0 +1,30 @@ +// Benchmarks defaultGetFormat() on `data:` URLs. The MIME-matching regex used +// to be susceptible to catastrophic backtracking on malformed input lacking a +// `,` separator (https://github.com/nodejs/node/issues/61904); `pathLength` +// scales the malformed path so a regression shows up as a sharp drop in ops/sec +// rather than a hang. +'use strict'; + +const common = require('../common.js'); + +const configs = { + n: [1e4], + pathLength: [1e2, 1e3, 1e4], +}; + +const options = { + flags: ['--expose-internals'], +}; + +const bench = common.createBenchmark(main, configs, options); + +function main({ n, pathLength }) { + const { defaultGetFormat } = require('internal/modules/esm/get_format'); + const url = new URL(`data:a/${'a'.repeat(pathLength)}B`); + + bench.start(); + for (let i = 0; i < n; i++) { + defaultGetFormat(url, { parentURL: undefined }); + } + bench.end(n); +} diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js index 4f334c7d88c336..78f338226cc137 100644 --- a/lib/internal/modules/esm/get_format.js +++ b/lib/internal/modules/esm/get_format.js @@ -97,7 +97,7 @@ function detectModuleFormat(source, url) { */ function getDataProtocolModuleFormat(parsed) { const { 1: mime } = RegExpPrototypeExec( - /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/, + /^([^/]+\/[^;,]+)(?:;[^,]*)?,/, parsed.pathname, ) || [ null, null, null ]; diff --git a/lib/internal/modules/esm/load.js b/lib/internal/modules/esm/load.js index c284163fba86ec..70c3fc89222bbf 100644 --- a/lib/internal/modules/esm/load.js +++ b/lib/internal/modules/esm/load.js @@ -205,7 +205,7 @@ function throwIfUnsupportedURLScheme(parsed) { */ function throwUnknownModuleFormat(url, format) { const dataUrl = RegExpPrototypeExec( - /^data:([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/, + /^data:([^/]+\/[^;,]+)(?:;[^,]*)?,/, url, );