From b5b66ef243d6d3f08027e80b668afc0a0275cc6b Mon Sep 17 00:00:00 2001 From: Francesco Trotta Date: Tue, 5 Oct 2021 07:42:08 +0200 Subject: [PATCH] lib: fix regular expression to detect `/` and `\` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/40325 Backport-PR-URL: https://github.com/nodejs/node/pull/40564 Fixes: https://github.com/nodejs/node/issues/40305 Reviewed-By: Michaƫl Zasso Reviewed-By: Antoine du Hamel Reviewed-By: Guy Bedford Reviewed-By: James M Snell Reviewed-By: Zeyu Yang --- lib/internal/modules/esm/resolve.js | 2 +- test/es-module/test-esm-encoded-path.mjs | 3 +++ test/es-module/test-esm-exports.mjs | 5 ++++- test/es-module/test-esm-imports.mjs | 6 ++++-- test/es-module/test-esm-pkgname.mjs | 4 ++++ test/fixtures/es-modules/pkgimports/package.json | 3 ++- test/fixtures/es-modules/test-esm-comma,.mjs | 1 + 7 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/es-modules/test-esm-comma,.mjs diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 162e0659bb8a36..87f28d5287612a 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -278,7 +278,7 @@ function resolveDirectoryEntry(search) { return resolveExtensions(new URL('index', search)); } -const encodedSepRegEx = /%2F|%2C/i; +const encodedSepRegEx = /%2F|%5C/i; function finalizeResolution(resolved, base) { if (RegExpPrototypeTest(encodedSepRegEx, resolved.pathname)) throw new ERR_INVALID_MODULE_SPECIFIER( diff --git a/test/es-module/test-esm-encoded-path.mjs b/test/es-module/test-esm-encoded-path.mjs index 351cb7eab887b4..067ce6066697b6 100644 --- a/test/es-module/test-esm-encoded-path.mjs +++ b/test/es-module/test-esm-encoded-path.mjs @@ -2,5 +2,8 @@ import '../common/index.mjs'; import assert from 'assert'; // ./test-esm-ok.mjs import ok from '../fixtures/es-modules/test-%65%73%6d-ok.mjs'; +// ./test-esm-comma,.mjs +import comma from '../fixtures/es-modules/test-esm-comma%2c.mjs'; assert(ok); +assert(comma); diff --git a/test/es-module/test-esm-exports.mjs b/test/es-module/test-esm-exports.mjs index a99814b0950d10..f1ef53ef2ffe3b 100644 --- a/test/es-module/test-esm-exports.mjs +++ b/test/es-module/test-esm-exports.mjs @@ -176,10 +176,13 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; })); } - // The use of %2F escapes in paths fails loading + // The use of %2F and %5C escapes in paths fails loading loadFixture('pkgexports/sub/..%2F..%2Fbar.js').catch(mustCall((err) => { strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); })); + loadFixture('pkgexports/sub/..%5C..%5Cbar.js').catch(mustCall((err) => { + strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); + })); // Package export with numeric index properties must throw a validation error loadFixture('pkgexports-numeric').catch(mustCall((err) => { diff --git a/test/es-module/test-esm-imports.mjs b/test/es-module/test-esm-imports.mjs index 577e33b60d08ec..5155e482a2d4fc 100644 --- a/test/es-module/test-esm-imports.mjs +++ b/test/es-module/test-esm-imports.mjs @@ -55,13 +55,15 @@ const { requireImport, importImport } = importer; // Backtracking below the package base ['#subpath/sub/../../../belowbase', 'request is not a valid subpath'], // Percent-encoded slash errors - ['#external/subpath/x%2Fy', 'must not include encoded "/"'], + ['#external/subpath/x%2Fy', 'must not include encoded "/" or "\\"'], + ['#external/subpath/x%5Cy', 'must not include encoded "/" or "\\"'], // Target must have a name ['#', '#'], // Initial slash target must have a leading name ['#/initialslash', '#/initialslash'], // Percent-encoded target paths - ['#percent', 'must not include encoded "/"'], + ['#encodedslash', 'must not include encoded "/" or "\\"'], + ['#encodedbackslash', 'must not include encoded "/" or "\\"'], ]); for (const [specifier, expected] of invalidImportSpecifiers) { diff --git a/test/es-module/test-esm-pkgname.mjs b/test/es-module/test-esm-pkgname.mjs index 06b5d2d104df63..5090d6c22ce689 100644 --- a/test/es-module/test-esm-pkgname.mjs +++ b/test/es-module/test-esm-pkgname.mjs @@ -7,6 +7,10 @@ importFixture('as%2Ff').catch(mustCall((err) => { strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); })); +importFixture('as%5Cf').catch(mustCall((err) => { + strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); +})); + importFixture('as\\df').catch(mustCall((err) => { strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); })); diff --git a/test/fixtures/es-modules/pkgimports/package.json b/test/fixtures/es-modules/pkgimports/package.json index 299ce9c197b554..5be55cecbd606c 100644 --- a/test/fixtures/es-modules/pkgimports/package.json +++ b/test/fixtures/es-modules/pkgimports/package.json @@ -26,6 +26,7 @@ "#": "./test.js", "#/initialslash": "./test.js", "#notfound": "./notfound.js", - "#percent": "./..%2F/x.js" + "#encodedslash": "./..%2F/x.js", + "#encodedbackslash": "./..%5C/x.js" } } diff --git a/test/fixtures/es-modules/test-esm-comma,.mjs b/test/fixtures/es-modules/test-esm-comma,.mjs new file mode 100644 index 00000000000000..0a5f91dc35ef5c --- /dev/null +++ b/test/fixtures/es-modules/test-esm-comma,.mjs @@ -0,0 +1 @@ +export default ',';