Merge pull request #10603 from robertbastian/octal

Fix false positives and false negatives in `octal_escapes`
This commit is contained in:
Manish Goregaokar 2023-04-13 15:50:00 -07:00 committed by GitHub
commit b2edd42b24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 46 deletions

View File

@ -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,6 +90,22 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
return;
}
span_lint_and_then(
cx,
OCTAL_ESCAPES,
span,
&format!(
"octal-looking escape in {} literal",
if is_string { "string" } else { "byte string" }
),
|diag| {
diag.help(format!(
"octal escapes are not supported, `\\0` is always a null {}",
if is_string { "character" } else { "byte" }
));
// 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();
@ -112,23 +128,10 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
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,
span,
&format!(
"octal-looking escape in {} literal",
if is_string { "string" } else { "byte string" }
),
|diag| {
diag.help(format!(
"octal escapes are not supported, `\\0` is always a null {}",
if is_string { "character" } else { "byte" }
));
suggest_1.push('"');
suggest_2.push('"');
// suggestion 1: equivalent hex escape
diag.span_suggestion(
span,
@ -146,6 +149,7 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
suggest_2,
Applicability::MaybeIncorrect,
);
}
},
);
}

View File

@ -17,4 +17,5 @@ fn main() {
let _good3 = "\0\0";
let _good4 = "X\0\0X";
let _good5 = "\0";
let _good6 = "\0\\01";
}

View File

@ -63,6 +63,22 @@ help: if the null character is intended, disambiguate using
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
|
@ -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