diff --git a/lib/linter/linter.js b/lib/linter/linter.js index 22cf17b54ba..26833d703ef 100644 --- a/lib/linter/linter.js +++ b/lib/linter/linter.js @@ -805,7 +805,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 ); diff --git a/lib/source-code/source-code.js b/lib/source-code/source-code.js index f3418e7e5b7..0b9c41ee6e1 100644 --- a/lib/source-code/source-code.js +++ b/lib/source-code/source-code.js @@ -935,7 +935,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 diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js index 6e98b93f3a1..d839fd5d9d4 100644 --- a/tests/lib/linter/linter.js +++ b/tests/lib/linter/linter.js @@ -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 */ @@ -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", () => {