Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions crates/oxc_linter/src/rules/eslint/no_new_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,22 @@ use oxc_span::{GetSpan, Ident, Span};

use crate::{AstNode, context::LintContext, rule::Rule};

fn no_new_func(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("The Function constructor is eval.").with_label(span)
fn no_new_func(function_call_span: Span, arguments_span: Option<Span>) -> OxcDiagnostic {
let mut diagnostic = OxcDiagnostic::warn("Using `new Function` or `Function` is not allowed.")
.with_help(
"Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.",
)
.with_note(
"The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.",
)
.with_label(function_call_span.primary_label("Dynamic function construction is used here."));

if let Some(arguments_span) = arguments_span {
diagnostic = diagnostic.and_label(
arguments_span.label("`Function` evaluates source text at runtime, similar to `eval`."),
);
}
diagnostic
}

#[derive(Debug, Default, Clone)]
Expand Down Expand Up @@ -53,14 +67,14 @@ impl Rule for NoNewFunc {
return;
};

check(id, new_expr.span, ctx);
check(id, new_expr.arguments_span(), ctx);
}
AstKind::CallExpression(call_expr) => {
let Some(obj_id) = call_expr.callee.get_identifier_reference() else {
return;
};

check(obj_id, call_expr.span, ctx);
check(obj_id, call_expr.arguments_span(), ctx);
}
member_expr if member_expr.is_member_expression_kind() => {
let Some(member_expr) = member_expr.as_member_expression_kind() else {
Expand Down Expand Up @@ -96,16 +110,16 @@ impl Rule for NoNewFunc {
return;
};

check(obj_id, parent_call_expr.span, ctx);
check(obj_id, parent_call_expr.arguments_span(), ctx);
}
_ => {}
}
}
}

fn check(ident: &IdentifierReference, span: Span, ctx: &LintContext) {
fn check(ident: &IdentifierReference, arguments_span: Option<Span>, ctx: &LintContext) {
if ident.is_global_reference_name(Ident::new_const("Function"), ctx.scoping()) {
ctx.diagnostic(no_new_func(span));
ctx.diagnostic(no_new_func(ident.span, arguments_span));
}
}

Expand Down
86 changes: 63 additions & 23 deletions crates/oxc_linter/src/snapshots/eslint_no_new_func.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,102 @@
source: crates/oxc_linter/src/tester.rs
---

⚠ eslint(no-new-func): The Function constructor is eval.
╭─[no_new_func.tsx:1:9]
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:13]
1 │ var a = new Function("b", "c", "return b+c");
· ────────────────────────────────────
· ────┬─── ───────────┬──────────
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:9]
1 │ var a = Function("b", "c", "return b+c");
· ────────────────────────────────
· ────┬─── ───────────┬──────────
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:9]
1 │ var a = Function.call(null, "b", "c", "return b+c");
· ───────────────────────────────────────────
· ────┬─── ──────────────┬─────────────
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:9]
1 │ var a = Function.apply(null, ["b", "c", "return b+c"]);
· ──────────────────────────────────────────────
· ────┬─── ───────────────┬──────────────
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:9]
1 │ var a = Function.bind(null, "b", "c", "return b+c")();
· ───────────────────────────────────────────
· ────┬─── ──────────────┬─────────────
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:9]
1 │ var a = Function.bind(null, "b", "c", "return b+c");
· ───────────────────────────────────────────
· ────┬─── ──────────────┬─────────────
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:9]
1 │ var a = Function["call"](null, "b", "c", "return b+c");
· ──────────────────────────────────────────────
· ────┬─── ──────────────┬─────────────
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
╭─[no_new_func.tsx:1:9]
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:10]
1 │ var a = (Function?.call)(null, "b", "c", "return b+c");
· ──────────────────────────────────────────────
· ────┬─── ──────────────┬─────────────
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
╭─[no_new_func.tsx:1:41]
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:45]
1 │ const fn = () => { class Function {} }; new Function('', '')
· ────────────────────
· ────┬─── ───┬──
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.

⚠ eslint(no-new-func): The Function constructor is eval.
⚠ eslint(no-new-func): Using `new Function` or `Function` is not allowed.
╭─[no_new_func.tsx:1:50]
1 │ var fn = function () { function Function() {} }; Function('', '')
· ────────────────
· ────┬─── ───┬──
· │ ╰── `Function` evaluates source text at runtime, similar to `eval`.
· ╰── Dynamic function construction is used here.
╰────
help: Avoid the `Function` constructor. Define the function directly with a function declaration/expression or an arrow function.
note: The `Function` constructor compiles code from strings at runtime, which can introduce injection risks, hurts performance, and makes code harder to analyze and maintain.
Loading