Skip to content

Commit 9d81532

Browse files
authored
fix: support __proto__ in /* exported */ comments (#21261)
* fix: support `__proto__` in `/* exported */` comments * bump @eslint/plugin-kit
1 parent 264b434 commit 9d81532

6 files changed

Lines changed: 69 additions & 2 deletions

File tree

lib/languages/js/source-code/source-code.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ class SourceCode extends TokenStore {
981981
applyInlineConfig() {
982982
const problems = [];
983983
const configs = [];
984-
const exportedVariables = {};
984+
const exportedVariables = Object.create(null);
985985
const inlineGlobals = Object.create(null);
986986

987987
this.getInlineConfigNodes().forEach(comment => {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
"@eslint/config-array": "^0.23.5",
138138
"@eslint/config-helpers": "^0.7.0",
139139
"@eslint/core": "^1.2.1",
140-
"@eslint/plugin-kit": "^0.7.2",
140+
"@eslint/plugin-kit": "^0.7.3",
141141
"@humanfs/node": "^0.16.6",
142142
"@humanwhocodes/module-importer": "^1.0.1",
143143
"@humanwhocodes/retry": "^0.4.2",

tests/lib/languages/js/source-code/source-code.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,6 +2442,16 @@ describe("SourceCode", () => {
24422442
assert.notOk(variable.eslintExported);
24432443
});
24442444
});
2445+
2446+
it("should mark exported variable named __proto__", () => {
2447+
const code = "/*exported __proto__ */ var __proto__;";
2448+
const globalScope = loadGlobalScope(code);
2449+
const variable = globalScope.get("__proto__");
2450+
2451+
assert.isDefined(variable);
2452+
assert.isTrue(variable.eslintUsed);
2453+
assert.isTrue(variable.eslintExported);
2454+
});
24452455
});
24462456

24472457
it("should extract rule configuration", () => {

tests/lib/linter/linter.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3160,6 +3160,19 @@ describe("Linter with FlatConfigArray", () => {
31603160
{ name: "__defineSetter__", writeable: true },
31613161
);
31623162
});
3163+
3164+
it("should define a global named __proto__", () => {
3165+
assertGlobalVariable(
3166+
"/*global __proto__ */",
3167+
{},
3168+
{ name: "__proto__", writeable: false },
3169+
);
3170+
assertGlobalVariable(
3171+
"/*global __proto__:writeable */",
3172+
{},
3173+
{ name: "__proto__", writeable: true },
3174+
);
3175+
});
31633176
});
31643177

31653178
describe("when evaluating code containing a /*global */ block with sloppy whitespace", () => {
@@ -3808,6 +3821,47 @@ describe("Linter with FlatConfigArray", () => {
38083821
linter.verify(code, config);
38093822
assert(spy && spy.calledOnce);
38103823
});
3824+
3825+
it("variable named __proto__ should be exported", () => {
3826+
const code = "/* exported __proto__ */\nvar __proto__;";
3827+
let spy;
3828+
const config = {
3829+
plugins: {
3830+
test: {
3831+
rules: {
3832+
checker: {
3833+
create(context) {
3834+
spy = sinon.spy(node => {
3835+
const scope =
3836+
context.sourceCode.getScope(
3837+
node,
3838+
),
3839+
proto = getVariable(
3840+
scope,
3841+
"__proto__",
3842+
);
3843+
3844+
assert.isTrue(proto.eslintUsed);
3845+
assert.isTrue(
3846+
proto.eslintExported,
3847+
);
3848+
});
3849+
3850+
return { Program: spy };
3851+
},
3852+
},
3853+
},
3854+
},
3855+
},
3856+
languageOptions: {
3857+
sourceType: "script",
3858+
},
3859+
rules: { "test/checker": "error" },
3860+
};
3861+
3862+
linter.verify(code, config);
3863+
assert(spy.calledOnce);
3864+
});
38113865
});
38123866

38133867
describe("/*eslint*/ Comments", () => {

tests/lib/rules/no-implicit-globals.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,8 @@ ruleTester.run("no-implicit-globals", rule, {
506506
languageOptions: { ecmaVersion: 2015 },
507507
},
508508
"/* exported foo, bar */ var foo = 1, bar = 2;",
509+
"/* exported __proto__ */ var __proto__ = 1;",
510+
"/* exported foo, __proto__, bar */ var foo = 1, __proto__ = 2, bar = 3;",
509511

510512
// `const`, `let` and `class`
511513
{

tests/lib/rules/no-unused-vars.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ ruleTester.run("no-unused-vars", rule, {
306306
// exported variables should work
307307
"/*exported toaster*/ var toaster = 'great'",
308308
"/*exported toaster, poster*/ var toaster = 1; poster = 0;",
309+
"/*exported __proto__*/ var __proto__ = 1;",
309310
{
310311
code: "/*exported x*/ var { x } = y",
311312
languageOptions: { ecmaVersion: 6 },

0 commit comments

Comments
 (0)