From d97140ecf4aeb0a1f8b391f46a31881f21ad93c3 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 11 Nov 2021 12:36:29 -0500 Subject: [PATCH] fix(eslint-plugin): [no-implied-eval] ignore locally declared functions (#4049) * fix(eslint-plugin): ignore redeclared variables * test: add test file for block setTimeout * fix: proper scope analysis --- .../src/rules/no-implied-eval.ts | 15 +++++++++- .../tests/rules/no-implied-eval.test.ts | 28 +++++++++++++++++++ 2 files changed, 42 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..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 { @@ -156,7 +165,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) && + 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 c789bd31121..f9c5bd137d6 100644 --- a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts +++ b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts @@ -276,6 +276,34 @@ class Foo { funcw(): void { setTimeout(this.a.b.c.bind(this), 1); } +} + `, + ` +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); + `, + ` +function setTimeout() {} + +{ + setTimeout(100); +} + `, + ` +function setTimeout() {} + +{ + setTimeout("alert('evil!')"); } `, ],