Skip to content

Commit

Permalink
fix: do not throw when defining a global named __defineSetter__ (esli…
Browse files Browse the repository at this point in the history
…nt#18364)

It replaced {} with `Object.create(null)` to avoid accessing
properties on the Object prototype.

fixes eslint#18363
  • Loading branch information
aladdin-add authored Apr 23, 2024
1 parent f12a02c commit eeec413
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/linter/linter.js
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ function createLanguageOptions({ globals: configuredGlobals, parser, parserOptio
*/
function resolveGlobals(providedGlobals, enabledEnvironments) {
return Object.assign(
{},
Object.create(null),
...enabledEnvironments.filter(env => env.globals).map(env => env.globals),
providedGlobals
);
Expand Down
2 changes: 1 addition & 1 deletion lib/source-code/source-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,7 @@ class SourceCode extends TokenStore {
* https://github.com/eslint/eslint/issues/16302
*/
const configGlobals = Object.assign(
{},
Object.create(null), // https://github.com/eslint/eslint/issues/18363
getGlobalsForEcmaVersion(languageOptions.ecmaVersion),
languageOptions.sourceType === "commonjs" ? globals.commonjs : void 0,
languageOptions.globals
Expand Down
51 changes: 51 additions & 0 deletions tests/lib/linter/linter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10250,6 +10250,48 @@ describe("Linter with FlatConfigArray", () => {

describe("when evaluating code containing /*global */ and /*globals */ blocks", () => {

/**
* Asserts the global variables in the provided code using the specified language options and data.
* @param {string} code The code to verify.
* @param {Object} languageOptions The language options to use.
* @param {Object} [data={}] Additional data for the assertion.
* @returns {void}
*/
function assertGlobalVariable(code, languageOptions, data = {}) {
let spy;

const config = {
plugins: {
test: {
rules: {
checker: {
create(context) {
spy = sinon.spy(node => {
const scope = context.sourceCode.getScope(node);
const g = getVariable(scope, data.name);

assert.strictEqual(g.name, data.name);
assert.strictEqual(g.writeable, data.writeable);
});

return { Program: spy };
}
}
}
}
},
rules: { "test/checker": "error" }
};

if (languageOptions !== void 0) {
config.languageOptions = languageOptions;
}

linter.verify(code, config);
assert(spy && spy.calledOnce);

}

it("variables should be available in global scope", () => {
const code = `
/*global a b:true c:false d:readable e:writeable Math:off */
Expand Down Expand Up @@ -10310,6 +10352,15 @@ describe("Linter with FlatConfigArray", () => {
linter.verify(code, config);
assert(spy && spy.calledOnce);
});

// https://github.com/eslint/eslint/issues/18363
it("not throw when defining a global named __defineSetter__", () => {
assertGlobalVariable("/*global __defineSetter__ */", {}, { name: "__defineSetter__", writeable: false });
assertGlobalVariable("/*global __defineSetter__ */", void 0, { name: "__defineSetter__", writeable: false });
assertGlobalVariable("/*global __defineSetter__ */", { globals: { __defineSetter__: "off" } }, { name: "__defineSetter__", writeable: false });
assertGlobalVariable("/*global __defineSetter__ */", { globals: { __defineSetter__: "writeable" } }, { name: "__defineSetter__", writeable: false });
assertGlobalVariable("/*global __defineSetter__:writeable */", {}, { name: "__defineSetter__", writeable: true });
});
});

describe("when evaluating code containing a /*global */ block with sloppy whitespace", () => {
Expand Down

0 comments on commit eeec413

Please sign in to comment.