From 4110eadc6778bd7b66a6fd74f39bf4e6ae13cea7 Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Tue, 24 Sep 2024 16:57:37 -0400 Subject: [PATCH] fix(linter): ignore invalid or partial disable directives --- crates/oxc_linter/src/disable_directives.rs | 103 +++++++++++++++++--- 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/crates/oxc_linter/src/disable_directives.rs b/crates/oxc_linter/src/disable_directives.rs index 6faa9534782c7a..669d5cd967e8cd 100644 --- a/crates/oxc_linter/src/disable_directives.rs +++ b/crates/oxc_linter/src/disable_directives.rs @@ -109,9 +109,8 @@ impl<'a> DisableDirectivesBuilder<'a> { self.disable_all_comments.push(comment.span); continue; } - // `eslint-disable-next-line` - if let Some(text) = text.strip_prefix("-next-line") { + else if let Some(text) = text.strip_prefix("-next-line") { // Get the span up to the next new line let stop = self.source_text[comment.span.end as usize..] .lines() @@ -136,9 +135,8 @@ impl<'a> DisableDirectivesBuilder<'a> { } continue; } - // `eslint-disable-line` - if let Some(text) = text.strip_prefix("-line") { + else if let Some(text) = text.strip_prefix("-line") { // Get the span between the preceding newline to this comment let start = self.source_text[..=comment.span.start as usize] .lines() @@ -162,16 +160,19 @@ impl<'a> DisableDirectivesBuilder<'a> { } continue; } - - // `eslint-disable rule-name1, rule-name2` - let mut rules = vec![]; - Self::get_rule_names(text, |rule_name| { - self.disable_start_map.entry(rule_name).or_insert(comment.span.end); - rules.push(rule_name); - }); - self.disable_rule_comments.push(DisableRuleComment { span: comment.span, rules }); - - continue; + // Remaining text should start with a space, else it's probably a typo of the correct syntax. + // Like `eslint-disable-lext-nine` where `text` is `-lext-nine`, or directive is `eslint-disablefoo` + else if text.starts_with(' ') { + // `eslint-disable rule-name1, rule-name2` + let mut rules = vec![]; + Self::get_rule_names(text, |rule_name| { + self.disable_start_map.entry(rule_name).or_insert(comment.span.end); + rules.push(rule_name); + }); + self.disable_rule_comments + .push(DisableRuleComment { span: comment.span, rules }); + continue; + } } if let Some(text) = @@ -341,6 +342,21 @@ fn test() { debugger; " ), + // Should only match `eslint-enable` comments, not `eslint-enablefoo` + format!(" + /* {prefix}-disable */ + debugger; + /* {prefix}-enablefoo */ + debugger; + " + ), + format!(" + /* {prefix}-disable no-debugger, no-console */ + debugger; + /* {prefix}-enablefoo no-debugger, no-console */ + debugger; + " + ), ]; let fail = vec![ @@ -395,6 +411,65 @@ fn test() { debugger; " ), + // Should not match invalid directives + // https://github.com/oxc-project/oxc/issues/6041 + format!( + "// {prefix}-disable-lext-nine no-debugger + debugger; + " + ), + format!( + "// {prefix}-disabled no-debugger + debugger; + " + ), + format!( + "// {prefix}-disabled + debugger; + " + ), + format!( + " + debugger; // {prefix}-disable-lext-nine no-debugger + + // {prefix}-disable-lext-nine no-debugger + debugger; + + debugger; /* {prefix}-disable-lin no-debugger */ + + /* {prefix}-disable-next-lin no-debugger */ + debugger; + " + ), + format!( + "debugger; // {prefix}-disable-linefoo + debugger; // {prefix}-disable-linefoo + + // {prefix}-disable-next-linefoo + debugger; + + /* {prefix}-disable-next-linefoo */ + debugger; + + debugger; /* {prefix}-disable-linefoo */ + " + ), + format!( + " + /* {prefix}-disable */ + debugger; + /* {prefix}-enable */ + debugger; + " + ), + format!( + " + /* {prefix}-disable no-debugger, no-console */ + debugger; + /* {prefix}-enable no-debugger, no-console */ + debugger; + " + ), ]; Tester::new("no-debugger", pass, fail).test();