about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRobert Bastian <robertbastian@google.com>2023-04-06 16:06:56 +0200
committerRobert Bastian <robertbastian@google.com>2023-04-06 16:31:50 +0200
commit67e836d4cfe4905dd1c4caa1d14f2aa7f76cc42a (patch)
tree26f888bc7692408c9ce7a64f2db375e01f8933e2
parentde5c6d6b1ed50246cf3d5c93b8d6e0b467dfbddf (diff)
downloadrust-67e836d4cfe4905dd1c4caa1d14f2aa7f76cc42a.tar.gz
rust-67e836d4cfe4905dd1c4caa1d14f2aa7f76cc42a.zip
fix
-rw-r--r--clippy_lints/src/octal_escapes.rs94
-rw-r--r--tests/ui/octal_escapes.rs1
-rw-r--r--tests/ui/octal_escapes.stderr18
3 files changed, 67 insertions, 46 deletions
diff --git a/clippy_lints/src/octal_escapes.rs b/clippy_lints/src/octal_escapes.rs
index 7376ab0c846..6d3865080a6 100644
--- a/clippy_lints/src/octal_escapes.rs
+++ b/clippy_lints/src/octal_escapes.rs
@@ -76,8 +76,8 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
         if ch == '\\' {
             if let Some((_, '0')) = iter.next() {
                 // collect up to two further octal digits
-                if let Some((mut to, '0'..='7')) = iter.next() {
-                    if let Some((_, '0'..='7')) = iter.peek() {
+                if let Some((mut to, _)) = iter.next_if(|(_, ch)| matches!(ch, '0'..='7')) {
+                    if iter.next_if(|(_, ch)| matches!(ch, '0'..='7')).is_some() {
                         to += 1;
                     }
                     found.push((from, to + 1));
@@ -90,32 +90,6 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
         return;
     }
 
-    // construct two suggestion strings, one with \x escapes with octal meaning
-    // as in C, and one with \x00 for null bytes.
-    let mut suggest_1 = if is_string { "\"" } else { "b\"" }.to_string();
-    let mut suggest_2 = suggest_1.clone();
-    let mut index = 0;
-    for (from, to) in found {
-        suggest_1.push_str(&contents[index..from]);
-        suggest_2.push_str(&contents[index..from]);
-
-        // construct a replacement escape
-        // the maximum value is \077, or \x3f, so u8 is sufficient here
-        if let Ok(n) = u8::from_str_radix(&contents[from + 1..to], 8) {
-            write!(suggest_1, "\\x{n:02x}").unwrap();
-        }
-
-        // append the null byte as \x00 and the following digits literally
-        suggest_2.push_str("\\x00");
-        suggest_2.push_str(&contents[from + 2..to]);
-
-        index = to;
-    }
-    suggest_1.push_str(&contents[index..]);
-    suggest_1.push('"');
-    suggest_2.push_str(&contents[index..]);
-    suggest_2.push('"');
-
     span_lint_and_then(
         cx,
         OCTAL_ESCAPES,
@@ -129,23 +103,53 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
                 "octal escapes are not supported, `\\0` is always a null {}",
                 if is_string { "character" } else { "byte" }
             ));
-            // suggestion 1: equivalent hex escape
-            diag.span_suggestion(
-                span,
-                "if an octal escape was intended, use the hexadecimal representation instead",
-                suggest_1,
-                Applicability::MaybeIncorrect,
-            );
-            // suggestion 2: unambiguous null byte
-            diag.span_suggestion(
-                span,
-                format!(
-                    "if the null {} is intended, disambiguate using",
-                    if is_string { "character" } else { "byte" }
-                ),
-                suggest_2,
-                Applicability::MaybeIncorrect,
-            );
+
+            // Generate suggestions if the string is not too long (~ 5 lines)
+            if contents.len() < 400 {
+                // construct two suggestion strings, one with \x escapes with octal meaning
+                // as in C, and one with \x00 for null bytes.
+                let mut suggest_1 = if is_string { "\"" } else { "b\"" }.to_string();
+                let mut suggest_2 = suggest_1.clone();
+                let mut index = 0;
+                for (from, to) in found {
+                    suggest_1.push_str(&contents[index..from]);
+                    suggest_2.push_str(&contents[index..from]);
+
+                    // construct a replacement escape
+                    // the maximum value is \077, or \x3f, so u8 is sufficient here
+                    if let Ok(n) = u8::from_str_radix(&contents[from + 1..to], 8) {
+                        write!(suggest_1, "\\x{n:02x}").unwrap();
+                    }
+
+                    // append the null byte as \x00 and the following digits literally
+                    suggest_2.push_str("\\x00");
+                    suggest_2.push_str(&contents[from + 2..to]);
+
+                    index = to;
+                }
+                suggest_1.push_str(&contents[index..]);
+                suggest_2.push_str(&contents[index..]);
+
+                suggest_1.push('"');
+                suggest_2.push('"');
+                // suggestion 1: equivalent hex escape
+                diag.span_suggestion(
+                    span,
+                    "if an octal escape was intended, use the hexadecimal representation instead",
+                    suggest_1,
+                    Applicability::MaybeIncorrect,
+                );
+                // suggestion 2: unambiguous null byte
+                diag.span_suggestion(
+                    span,
+                    format!(
+                        "if the null {} is intended, disambiguate using",
+                        if is_string { "character" } else { "byte" }
+                    ),
+                    suggest_2,
+                    Applicability::MaybeIncorrect,
+                );
+            }
         },
     );
 }
diff --git a/tests/ui/octal_escapes.rs b/tests/ui/octal_escapes.rs
index 53145ef0fd2..61ea9660457 100644
--- a/tests/ui/octal_escapes.rs
+++ b/tests/ui/octal_escapes.rs
@@ -17,4 +17,5 @@ fn main() {
     let _good3 = "\0\0";
     let _good4 = "X\0\0X";
     let _good5 = "锈\0锈";
+    let _good6 = "\0\\01";
 }
diff --git a/tests/ui/octal_escapes.stderr b/tests/ui/octal_escapes.stderr
index 295dc1798e3..aa362e96321 100644
--- a/tests/ui/octal_escapes.stderr
+++ b/tests/ui/octal_escapes.stderr
@@ -64,6 +64,22 @@ LL |     let _bad4 = "/x001234567";
    |                 ~~~~~~~~~~~~~
 
 error: octal-looking escape in string literal
+  --> $DIR/octal_escapes.rs:9:17
+   |
+LL |     let _bad5 = "/0/03";
+   |                 ^^^^^^^
+   |
+   = help: octal escapes are not supported, `/0` is always a null character
+help: if an octal escape was intended, use the hexadecimal representation instead
+   |
+LL |     let _bad5 = "/0/x03";
+   |                 ~~~~~~~~
+help: if the null character is intended, disambiguate using
+   |
+LL |     let _bad5 = "/0/x003";
+   |                 ~~~~~~~~~
+
+error: octal-looking escape in string literal
   --> $DIR/octal_escapes.rs:10:17
    |
 LL |     let _bad6 = "Text-/055/077-MoreText";
@@ -127,5 +143,5 @@ help: if the null character is intended, disambiguate using
 LL |     let _bad9 = "锈/x0011锈";
    |                 ~~~~~~~~~~~~
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors