Skip to content

Commit 8d05604

Browse files
authored
Merge pull request #347 from webpack/fix/issue-346
fix imports field
2 parents ddc96f8 + 9abcc87 commit 8d05604

File tree

8 files changed

+68
-12
lines changed

8 files changed

+68
-12
lines changed

lib/ExportsFieldPlugin.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const DescriptionFileUtils = require("./DescriptionFileUtils");
1010
const forEachBail = require("./forEachBail");
1111
const { processExportsField } = require("./util/entrypoints");
1212
const { parseIdentifier } = require("./util/identifier");
13-
const { checkExportsFieldTarget } = require("./util/path");
13+
const { checkImportsExportsFieldTarget } = require("./util/path");
1414

1515
/** @typedef {import("./Resolver")} Resolver */
1616
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
@@ -116,7 +116,7 @@ module.exports = class ExportsFieldPlugin {
116116

117117
const [relativePath, query, fragment] = parsedIdentifier;
118118

119-
const error = checkExportsFieldTarget(relativePath);
119+
const error = checkImportsExportsFieldTarget(relativePath);
120120

121121
if (error) {
122122
return callback(error);

lib/ImportsFieldPlugin.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const DescriptionFileUtils = require("./DescriptionFileUtils");
1010
const forEachBail = require("./forEachBail");
1111
const { processImportsField } = require("./util/entrypoints");
1212
const { parseIdentifier } = require("./util/identifier");
13+
const { checkImportsExportsFieldTarget } = require("./util/path");
1314

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

119120
const [path_, query, fragment] = parsedIdentifier;
120121

122+
const error = checkImportsExportsFieldTarget(path_);
123+
124+
if (error) {
125+
return callback(error);
126+
}
127+
121128
switch (path_.charCodeAt(0)) {
122129
// should be relative
123130
case dotCode: {

lib/util/path.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ const cachedJoin = (rootPath, request) => {
192192
};
193193
exports.cachedJoin = cachedJoin;
194194

195-
const checkExportsFieldTarget = relativePath => {
196-
let lastNonSlashIndex = 2;
197-
let slashIndex = relativePath.indexOf("/", 2);
195+
const checkImportsExportsFieldTarget = relativePath => {
196+
let lastNonSlashIndex = 0;
197+
let slashIndex = relativePath.indexOf("/", 1);
198198
let cd = 0;
199199

200200
while (slashIndex !== -1) {
@@ -209,6 +209,8 @@ const checkExportsFieldTarget = relativePath => {
209209
);
210210
break;
211211
}
212+
case ".":
213+
break;
212214
default:
213215
cd++;
214216
break;
@@ -218,4 +220,4 @@ const checkExportsFieldTarget = relativePath => {
218220
slashIndex = relativePath.indexOf("/", lastNonSlashIndex);
219221
}
220222
};
221-
exports.checkExportsFieldTarget = checkExportsFieldTarget;
223+
exports.checkImportsExportsFieldTarget = checkImportsExportsFieldTarget;

test/exportsField.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const CachedInputFileSystem = require("../lib/CachedInputFileSystem");
1010
const fixture = path.resolve(__dirname, "fixtures", "exports-field");
1111
const fixture2 = path.resolve(__dirname, "fixtures", "exports-field2");
1212
const fixture3 = path.resolve(__dirname, "fixtures", "exports-field3");
13+
const fixture4 = path.resolve(__dirname, "fixtures", "exports-field-error");
1314

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

2395+
it("should throw error if target is invalid", done => {
2396+
resolver.resolve({}, fixture4, "exports-field", {}, (err, result) => {
2397+
if (!err) throw new Error(`expect error, got ${result}`);
2398+
err.should.be.instanceof(Error);
2399+
err.message.should.match(/Trying to access out of package scope/);
2400+
done();
2401+
});
2402+
});
2403+
23942404
it("throw error if exports field is invalid", done => {
23952405
resolver.resolve(
23962406
{},

test/fixtures/exports-field-error/node_modules/exports-field/package.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixtures/exports-field-error/node_modules/pack1/index.js

Whitespace-only changes.

test/importsField.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,11 +1211,11 @@ describe("ImportsFieldPlugin", () => {
12111211
);
12121212
});
12131213

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

1232-
resolver.resolve({}, fixture, "#b", {}, (err, result) => {
1232+
resolver.resolve({}, fixture, "#imports-field", {}, (err, result) => {
12331233
if (err) return done(err);
12341234
if (!result) throw new Error("No result");
1235-
result.should.equal(path.resolve(fixture, "../b.js"));
1235+
result.should.equal(path.resolve(fixture, "./b.js"));
12361236
done();
12371237
});
12381238
});

test/path.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
require("should");
2+
3+
const { checkImportsExportsFieldTarget } = require("../lib/util/path");
4+
5+
describe("checkImportsExportsFieldTarget", () => {
6+
/**
7+
* @type {string[]}
8+
*/
9+
const errorCases = [
10+
"../a.js",
11+
"../",
12+
"./a/b/../../../c.js",
13+
"./a/b/../../../",
14+
"./../../c.js",
15+
"./../../",
16+
"./a/../b/../../c.js",
17+
"./a/../b/../../",
18+
"./././../"
19+
];
20+
21+
errorCases.forEach(case_ => {
22+
it(case_, done => {
23+
const error = checkImportsExportsFieldTarget(case_);
24+
if (!error) return done("expect error");
25+
error.should.be.instanceof(Error);
26+
error.message.should.match(/Trying to access out of package scope/);
27+
done();
28+
});
29+
});
30+
});

0 commit comments

Comments
 (0)