Skip to content

Commit

Permalink
fix(eslint-plugin): [no-implied-eval] ignore locally declared functio…
Browse files Browse the repository at this point in the history
…ns (#4049)

* fix(eslint-plugin): ignore redeclared variables

* test: add test file for block setTimeout

* fix: proper scope analysis
  • Loading branch information
Josh Goldberg committed Nov 11, 2021
1 parent 844c25e commit d97140e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
15 changes: 14 additions & 1 deletion packages/eslint-plugin/src/rules/no-implied-eval.ts
Expand Up @@ -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 {
Expand Down Expand Up @@ -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' });
}
}
Expand Down
28 changes: 28 additions & 0 deletions packages/eslint-plugin/tests/rules/no-implied-eval.test.ts
Expand Up @@ -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!')");
}
`,
],
Expand Down

0 comments on commit d97140e

Please sign in to comment.