diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__dont_panic_on_8_in_octal_escape.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__dont_panic_on_8_in_octal_escape.snap new file mode 100644 index 0000000000000..8b8c0a4e68b5f --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__dont_panic_on_8_in_octal_escape.snap @@ -0,0 +1,28 @@ +--- +source: crates/ruff_python_parser/src/string.rs +expression: parse_ast +--- +[ + Assign( + StmtAssign { + range: 0..16, + targets: [ + Name( + ExprName { + range: 0..4, + id: "bold", + ctx: Store, + }, + ), + ], + value: StringLiteral( + ExprStringLiteral { + range: 7..16, + value: "\u{3}8[1m", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), +] diff --git a/crates/ruff_python_parser/src/string.rs b/crates/ruff_python_parser/src/string.rs index 64c0834e80321..ab9afff50a935 100644 --- a/crates/ruff_python_parser/src/string.rs +++ b/crates/ruff_python_parser/src/string.rs @@ -114,7 +114,7 @@ impl<'a> StringParser<'a> { let mut len = 1; while len < 3 { - let Some(b'0'..=b'8') = self.peek_byte() else { + let Some(b'0'..=b'7') = self.peek_byte() else { break; }; @@ -885,6 +885,15 @@ mod tests { insta::assert_debug_snapshot!(parse_ast); } + /// https://github.com/astral-sh/ruff/issues/8355 + #[test] + fn test_dont_panic_on_8_in_octal_escape() { + let source = r#"bold = '\038[1m'"#; + let parse_ast = parse_suite(source, "").unwrap(); + + insta::assert_debug_snapshot!(parse_ast); + } + macro_rules! test_aliases_parse { ($($name:ident: $alias:expr,)*) => { $(