From 911e54290c08b44a7a1b8e94ffcab3da0fb64532 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 25 Oct 2021 01:56:27 -0400 Subject: [PATCH 1/3] fix(eslint-plugin): ignore redeclared variables --- .../eslint-plugin/src/rules/no-implied-eval.ts | 6 +++++- .../tests/rules/no-implied-eval.test.ts | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index 91bf0d0d319..04ff7d0e50c 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -156,7 +156,11 @@ export default util.createRule({ } const [handler] = node.arguments; - if (EVAL_LIKE_METHODS.has(calleeName) && !isFunction(handler)) { + if ( + EVAL_LIKE_METHODS.has(calleeName) && + !isFunction(handler) && + !context.getScope().variables.some(v => v.name === calleeName) + ) { context.report({ node: handler, messageId: 'noImpliedEvalError' }); } } diff --git a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts index c789bd31121..f01551f1b95 100644 --- a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts +++ b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts @@ -278,6 +278,20 @@ class Foo { } } `, + ` +function setTimeout(input: string, value: number) {} + +setTimeout('', 0); + `, + ` +declare module 'my-timers-promises' { + export function setTimeout(ms: number): void; +} + +import { setTimeout } from 'my-timers-promises'; + +setTimeout(1000); + `, ], invalid: [ From 52a2b3193c07fb635551ec40afca1bc4e010df3e Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 5 Nov 2021 00:16:24 -0400 Subject: [PATCH 2/3] test: add test file for block setTimeout --- packages/eslint-plugin/tests/rules/no-implied-eval.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts index f01551f1b95..f362bed4443 100644 --- a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts +++ b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts @@ -292,6 +292,13 @@ import { setTimeout } from 'my-timers-promises'; setTimeout(1000); `, + ` +function setTimeout() {} + +{ + setTimeout(); +} + `, ], invalid: [ From 49bcd084873d412771349a13967ef8d96b1150dd Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 11 Nov 2021 11:11:42 -0500 Subject: [PATCH 3/3] fix: proper scope analysis --- packages/eslint-plugin/src/rules/no-implied-eval.ts | 11 ++++++++++- .../eslint-plugin/tests/rules/no-implied-eval.test.ts | 9 ++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index 04ff7d0e50c..8e19481653d 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -123,6 +123,15 @@ export default util.createRule({ } } + function isReferenceToGlobalFunction(calleeName: string): boolean { + const ref = context + .getScope() + .references.find(ref => ref.identifier.name === calleeName); + + // ensure it's the "global" version + return !ref?.resolved || ref.resolved.defs.length === 0; + } + function checkImpliedEval( node: TSESTree.NewExpression | TSESTree.CallExpression, ): void { @@ -159,7 +168,7 @@ export default util.createRule({ if ( EVAL_LIKE_METHODS.has(calleeName) && !isFunction(handler) && - !context.getScope().variables.some(v => v.name === calleeName) + isReferenceToGlobalFunction(calleeName) ) { context.report({ node: handler, messageId: 'noImpliedEvalError' }); } diff --git a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts index f362bed4443..f9c5bd137d6 100644 --- a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts +++ b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts @@ -296,7 +296,14 @@ setTimeout(1000); function setTimeout() {} { - setTimeout(); + setTimeout(100); +} + `, + ` +function setTimeout() {} + +{ + setTimeout("alert('evil!')"); } `, ],