Skip to content

Commit

Permalink
fix imports field
Browse files Browse the repository at this point in the history
throw error in imports field if trying to access out of package scope
  • Loading branch information
vankop committed May 23, 2022
1 parent ddc96f8 commit 9abcc87
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 12 deletions.
4 changes: 2 additions & 2 deletions lib/ExportsFieldPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const DescriptionFileUtils = require("./DescriptionFileUtils");
const forEachBail = require("./forEachBail");
const { processExportsField } = require("./util/entrypoints");
const { parseIdentifier } = require("./util/identifier");
const { checkExportsFieldTarget } = require("./util/path");
const { checkImportsExportsFieldTarget } = require("./util/path");

/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
Expand Down Expand Up @@ -116,7 +116,7 @@ module.exports = class ExportsFieldPlugin {

const [relativePath, query, fragment] = parsedIdentifier;

const error = checkExportsFieldTarget(relativePath);
const error = checkImportsExportsFieldTarget(relativePath);

if (error) {
return callback(error);
Expand Down
7 changes: 7 additions & 0 deletions lib/ImportsFieldPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const DescriptionFileUtils = require("./DescriptionFileUtils");
const forEachBail = require("./forEachBail");
const { processImportsField } = require("./util/entrypoints");
const { parseIdentifier } = require("./util/identifier");
const { checkImportsExportsFieldTarget } = require("./util/path");

/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
Expand Down Expand Up @@ -118,6 +119,12 @@ module.exports = class ImportsFieldPlugin {

const [path_, query, fragment] = parsedIdentifier;

const error = checkImportsExportsFieldTarget(path_);

if (error) {
return callback(error);
}

switch (path_.charCodeAt(0)) {
// should be relative
case dotCode: {
Expand Down
10 changes: 6 additions & 4 deletions lib/util/path.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ const cachedJoin = (rootPath, request) => {
};
exports.cachedJoin = cachedJoin;

const checkExportsFieldTarget = relativePath => {
let lastNonSlashIndex = 2;
let slashIndex = relativePath.indexOf("/", 2);
const checkImportsExportsFieldTarget = relativePath => {
let lastNonSlashIndex = 0;
let slashIndex = relativePath.indexOf("/", 1);
let cd = 0;

while (slashIndex !== -1) {
Expand All @@ -209,6 +209,8 @@ const checkExportsFieldTarget = relativePath => {
);
break;
}
case ".":
break;
default:
cd++;
break;
Expand All @@ -218,4 +220,4 @@ const checkExportsFieldTarget = relativePath => {
slashIndex = relativePath.indexOf("/", lastNonSlashIndex);
}
};
exports.checkExportsFieldTarget = checkExportsFieldTarget;
exports.checkImportsExportsFieldTarget = checkImportsExportsFieldTarget;
10 changes: 10 additions & 0 deletions test/exportsField.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const CachedInputFileSystem = require("../lib/CachedInputFileSystem");
const fixture = path.resolve(__dirname, "fixtures", "exports-field");
const fixture2 = path.resolve(__dirname, "fixtures", "exports-field2");
const fixture3 = path.resolve(__dirname, "fixtures", "exports-field3");
const fixture4 = path.resolve(__dirname, "fixtures", "exports-field-error");

describe("Process exports field", function exportsField() {
/** @type {Array<{name: string, expect: string[]|Error, suite: [ExportsField, string, string[]]}>} */
Expand Down Expand Up @@ -2391,6 +2392,15 @@ describe("ExportsFieldPlugin", () => {
});
});

it("should throw error if target is invalid", done => {
resolver.resolve({}, fixture4, "exports-field", {}, (err, result) => {
if (!err) throw new Error(`expect error, got ${result}`);
err.should.be.instanceof(Error);
err.message.should.match(/Trying to access out of package scope/);
done();
});
});

it("throw error if exports field is invalid", done => {
resolver.resolve(
{},
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
12 changes: 6 additions & 6 deletions test/importsField.js
Original file line number Diff line number Diff line change
Expand Up @@ -1211,11 +1211,11 @@ describe("ImportsFieldPlugin", () => {
);
});

it("should resolve out of package scope", done => {
it("should disallow resolve out of package scope", done => {
resolver.resolve({}, fixture, "#b", {}, (err, result) => {
if (err) return done(err);
if (!result) throw new Error("No result");
result.should.equal(path.resolve(fixture, "../b.js"));
if (!err) throw new Error(`expect error, got ${result}`);
err.should.be.instanceof(Error);
err.message.should.match(/Trying to access out of package scope/);
done();
});
});
Expand All @@ -1229,10 +1229,10 @@ describe("ImportsFieldPlugin", () => {
conditionNames: ["webpack"]
});

resolver.resolve({}, fixture, "#b", {}, (err, result) => {
resolver.resolve({}, fixture, "#imports-field", {}, (err, result) => {
if (err) return done(err);
if (!result) throw new Error("No result");
result.should.equal(path.resolve(fixture, "../b.js"));
result.should.equal(path.resolve(fixture, "./b.js"));
done();
});
});
Expand Down
30 changes: 30 additions & 0 deletions test/path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require("should");

const { checkImportsExportsFieldTarget } = require("../lib/util/path");

describe("checkImportsExportsFieldTarget", () => {
/**
* @type {string[]}
*/
const errorCases = [
"../a.js",
"../",
"./a/b/../../../c.js",
"./a/b/../../../",
"./../../c.js",
"./../../",
"./a/../b/../../c.js",
"./a/../b/../../",
"./././../"
];

errorCases.forEach(case_ => {
it(case_, done => {
const error = checkImportsExportsFieldTarget(case_);
if (!error) return done("expect error");
error.should.be.instanceof(Error);
error.message.should.match(/Trying to access out of package scope/);
done();
});
});
});

0 comments on commit 9abcc87

Please sign in to comment.