From 05172951acf2649b0dae22bdff5f0adb7c8ab8d0 Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Fri, 22 Nov 2019 10:34:31 -0600 Subject: [PATCH] esm: data URLs should ignore unknown parameters PR-URL: https://github.com/nodejs/node/pull/30593 Reviewed-By: Jan Krems Reviewed-By: Guy Bedford --- lib/internal/modules/esm/default_resolve.js | 2 +- lib/internal/modules/esm/translators.js | 2 +- test/es-module/test-esm-data-urls.js | 41 +++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/internal/modules/esm/default_resolve.js b/lib/internal/modules/esm/default_resolve.js index 5271c6a0fe0a02..f436bc2a1a1d84 100644 --- a/lib/internal/modules/esm/default_resolve.js +++ b/lib/internal/modules/esm/default_resolve.js @@ -53,7 +53,7 @@ function resolve(specifier, parentURL) { try { const parsed = new URL(specifier); if (parsed.protocol === 'data:') { - const [ , mime ] = /^([^/]+\/[^;,]+)(;base64)?,/.exec(parsed.pathname) || [ null, null, null ]; + const [ , mime ] = /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/.exec(parsed.pathname) || [ null, null, null ]; const format = ({ '__proto__': null, 'text/javascript': 'module', diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 34a9a140dd7732..76bd3fe04e320d 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -39,7 +39,7 @@ const debug = debuglog('esm'); const translators = new SafeMap(); exports.translators = translators; -const DATA_URL_PATTERN = /^[^/]+\/[^,;]+(;base64)?,([\s\S]*)$/; +const DATA_URL_PATTERN = /^[^/]+\/[^,;]+(?:[^,]*?)(;base64)?,([\s\S]*)$/; function getSource(url) { const parsed = new URL(url); if (parsed.protocol === 'file:') { diff --git a/test/es-module/test-esm-data-urls.js b/test/es-module/test-esm-data-urls.js index 963f26c3e48bf2..221d91337ec8d1 100644 --- a/test/es-module/test-esm-data-urls.js +++ b/test/es-module/test-esm-data-urls.js @@ -37,6 +37,47 @@ function createBase64URL(mime, body) { assert.deepStrictEqual(Object.keys(ns), ['default']); assert.deepStrictEqual(ns.default, plainESMURL); } + { + const body = 'export default import.meta.url;'; + const plainESMURL = createURL('text/javascript;charset=UTF-8', body); + const ns = await import(plainESMURL); + assert.deepStrictEqual(Object.keys(ns), ['default']); + assert.deepStrictEqual(ns.default, plainESMURL); + } + { + const body = 'export default import.meta.url;'; + const plainESMURL = createURL('text/javascript;charset="UTF-8"', body); + const ns = await import(plainESMURL); + assert.deepStrictEqual(Object.keys(ns), ['default']); + assert.deepStrictEqual(ns.default, plainESMURL); + } + { + const body = 'export default import.meta.url;'; + const plainESMURL = createURL('text/javascript;;a=a;b=b;;', body); + const ns = await import(plainESMURL); + assert.deepStrictEqual(Object.keys(ns), ['default']); + assert.deepStrictEqual(ns.default, plainESMURL); + } + { + const ns = await import('data:application/json;foo="test,"this"'); + assert.deepStrictEqual(Object.keys(ns), ['default']); + assert.deepStrictEqual(ns.default, 'this'); + } + { + const ns = await import(`data:application/json;foo=${ + encodeURIComponent('test,') + },0`); + assert.deepStrictEqual(Object.keys(ns), ['default']); + assert.deepStrictEqual(ns.default, 0); + } + { + await assert.rejects(async () => { + return import('data:application/json;foo="test,",0'); + }, { + name: 'SyntaxError', + message: /Unexpected end of JSON input/ + }); + } { const body = '{"x": 1}'; const plainESMURL = createURL('application/json', body);