From 134e15e6571e31be185156b0dbcfc8644c7e7c7c Mon Sep 17 00:00:00 2001 From: Jose <48152124+JoSeBu1@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:01:15 +0100 Subject: [PATCH] feat(linter): eslint/no-proto (#2760) Rule detail: https://eslint.org/docs/latest/rules/no-proto --------- Co-authored-by: j.buendia --- crates/oxc_linter/src/rules.rs | 2 + .../oxc_linter/src/rules/eslint/no_proto.rs | 77 +++++++++++++++++++ crates/oxc_linter/src/snapshots/no_proto.snap | 31 ++++++++ 3 files changed, 110 insertions(+) create mode 100644 crates/oxc_linter/src/rules/eslint/no_proto.rs create mode 100644 crates/oxc_linter/src/snapshots/no_proto.snap diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index e75606384..914592928 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -86,6 +86,7 @@ mod eslint { pub mod no_new_wrappers; pub mod no_nonoctal_decimal_escape; pub mod no_obj_calls; + pub mod no_proto; pub mod no_prototype_builtins; pub mod no_redeclare; pub mod no_regex_spaces; @@ -408,6 +409,7 @@ oxc_macros::declare_all_lint_rules! { eslint::no_new_wrappers, eslint::no_nonoctal_decimal_escape, eslint::no_obj_calls, + eslint::no_proto, eslint::no_prototype_builtins, eslint::no_redeclare, eslint::no_regex_spaces, diff --git a/crates/oxc_linter/src/rules/eslint/no_proto.rs b/crates/oxc_linter/src/rules/eslint/no_proto.rs new file mode 100644 index 000000000..594607198 --- /dev/null +++ b/crates/oxc_linter/src/rules/eslint/no_proto.rs @@ -0,0 +1,77 @@ +use oxc_ast::AstKind; +use oxc_diagnostics::{ + miette::{self, Diagnostic}, + thiserror::Error, +}; +use oxc_macros::declare_oxc_lint; +use oxc_span::{GetSpan, Span}; + +use crate::{context::LintContext, rule::Rule, AstNode}; + +#[derive(Debug, Error, Diagnostic)] +#[error("eslint(no-proto): The '__proto__' property is deprecated")] +#[diagnostic(severity(warning), help("Disallow the use of the `__proto__` property."))] +struct NoProtoDiagnostic(#[label] pub Span); + +#[derive(Debug, Default, Clone)] +pub struct NoProto; + +declare_oxc_lint!( + /// ### What it does + /// Disallow the use of the __proto__ property + /// + /// ### Why is this bad? + /// __proto__ property has been deprecated as of ECMAScript 3.1 and shouldn’t be used in the code. Use Object.getPrototypeOf and Object.setPrototypeOf instead. + /// + /// ### Example + /// ```javascript + /// /*eslint no-proto: "error"*/ + /// + /// var a = obj.__proto__; + /// + /// var a = obj["__proto__"]; + /// + /// obj.__proto__ = b; + /// + /// obj["__proto__"] = b; + /// ``` + NoProto, + correctness +); + +impl Rule for NoProto { + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { + let AstKind::MemberExpression(member_expression) = node.kind() else { return }; + if let Some(static_property_name) = member_expression.static_property_name() { + if static_property_name == "__proto__" { + ctx.diagnostic(NoProtoDiagnostic(Span::new( + member_expression.span().start, + member_expression.span().end, + ))); + } + } + } +} + +#[test] +fn test() { + use crate::tester::Tester; + + let pass = vec![ + "var a = test[__proto__];", + "var __proto__ = null;", + "foo[`__proto`] = null;", + "foo[`__proto__ + `] = null;", + "class C { #__proto__; foo() { this.#__proto__; } }", + ]; + + let fail = vec![ + "var a = test.__proto__;", + "var a = test['__proto__'];", + "var a = test[`__proto__`];", + "test[`__proto__`] = function () {};", + ]; + + Tester::new(NoProto::NAME, pass, fail).test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/snapshots/no_proto.snap b/crates/oxc_linter/src/snapshots/no_proto.snap new file mode 100644 index 000000000..b66a84fe8 --- /dev/null +++ b/crates/oxc_linter/src/snapshots/no_proto.snap @@ -0,0 +1,31 @@ +--- +source: crates/oxc_linter/src/tester.rs +expression: no_proto +--- + ⚠ eslint(no-proto): The '__proto__' property is deprecated + ╭─[no_proto.tsx:1:9] + 1 │ var a = test.__proto__; + · ────────────── + ╰──── + help: Disallow the use of the `__proto__` property. + + ⚠ eslint(no-proto): The '__proto__' property is deprecated + ╭─[no_proto.tsx:1:9] + 1 │ var a = test['__proto__']; + · ───────────────── + ╰──── + help: Disallow the use of the `__proto__` property. + + ⚠ eslint(no-proto): The '__proto__' property is deprecated + ╭─[no_proto.tsx:1:9] + 1 │ var a = test[`__proto__`]; + · ───────────────── + ╰──── + help: Disallow the use of the `__proto__` property. + + ⚠ eslint(no-proto): The '__proto__' property is deprecated + ╭─[no_proto.tsx:1:1] + 1 │ test[`__proto__`] = function () {}; + · ───────────────── + ╰──── + help: Disallow the use of the `__proto__` property.