From 3c7d7c07752424c0147ef9dd7899675c23e118d8 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 4 Jan 2024 17:35:23 +0800 Subject: [PATCH] `no-thenable`: Fix crash on `{[Symbol.prototype]: 0}` (#2248) --- rules/no-thenable.js | 14 ++++++++++---- test/no-thenable.mjs | 10 ++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/rules/no-thenable.js b/rules/no-thenable.js index ef2713e983..2aa903bd2f 100644 --- a/rules/no-thenable.js +++ b/rules/no-thenable.js @@ -13,6 +13,15 @@ const messages = { const isStringThen = (node, context) => getStaticValue(node, context.sourceCode.getScope(node))?.value === 'then'; +const isPropertyThen = (node, context) => { + // `getPropertyName` throws on `({[Symbol.prototype]: 0})` + // https://github.com/eslint-community/eslint-utils/pull/182 + try { + return getPropertyName(node, context.sourceCode.getScope(node)) === 'then'; + } catch {} + + return false; +}; const cases = [ // `{then() {}}`, @@ -23,10 +32,7 @@ const cases = [ selector: 'ObjectExpression', * getNodes(node, context) { for (const property of node.properties) { - if ( - property.type === 'Property' - && getPropertyName(property, context.sourceCode.getScope(property)) === 'then' - ) { + if (property.type === 'Property' && isPropertyThen(property, context)) { yield property.key; } } diff --git a/test/no-thenable.mjs b/test/no-thenable.mjs index 581fd763bc..c337c63376 100644 --- a/test/no-thenable.mjs +++ b/test/no-thenable.mjs @@ -13,6 +13,7 @@ test.snapshot({ 'const foo = {[then]: 1}', 'const NOT_THEN = "no-then";const foo = {[NOT_THEN]: 1}', 'function foo({then}) {}', + '({[Symbol.prototype]: 1})', // `class` 'class then {}', @@ -35,6 +36,11 @@ test.snapshot({ 'class Foo {static get #then() {}}', 'class Foo {static get [then]() {}}', 'class Foo {notThen = then}', + 'class Foo {[Symbol.property]}', + 'class Foo {static [Symbol.property]}', + 'class Foo {get [Symbol.property]() {}}', + 'class Foo {[Symbol.property]() {}}', + 'class Foo {static get [Symbol.property]() {}}', // Assign 'foo[then] = 1', @@ -46,6 +52,7 @@ test.snapshot({ 'delete foo.then', 'typeof foo.then', 'foo.then != 1', + 'foo[Symbol.property] = 1', // `Object.fromEntries` 'Object.fromEntries([then, 1])', @@ -60,6 +67,7 @@ test.snapshot({ 'Object.fromEntries([[..."then", 1]])', 'Object.fromEntries([["then", 1]], extraArgument)', 'Object.fromEntries(...[["then", 1]])', + 'Object.fromEntries([[Symbol.property, 1]])', // `{Object,Reflect}.defineProperty` 'Object.defineProperty(foo, then, 1)', @@ -71,6 +79,8 @@ test.snapshot({ 'Object.defineProperty(foo, "then", )', 'Object.defineProperty(...foo, "then", 1)', 'Object.defineProperty(foo, ...["then", 1])', + 'Object.defineProperty(foo, Symbol.property, 1)', + 'Reflect.defineProperty(foo, Symbol.property, 1)', // `export` 'export {default} from "then"',