From a88899ed750047a4871f92940be415e447aef7a3 Mon Sep 17 00:00:00 2001 From: +merlan #flirora Date: Thu, 8 Aug 2024 12:06:22 -0400 Subject: [PATCH] Bail out of reparse in `expr_with_paren` if we land on a different char (#4577) --- crates/typst-syntax/src/parser.rs | 8 ++++++-- tests/suite/syntax/bugs.typ | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/suite/syntax/bugs.typ diff --git a/crates/typst-syntax/src/parser.rs b/crates/typst-syntax/src/parser.rs index ff01bacf..2cbce1d7 100644 --- a/crates/typst-syntax/src/parser.rs +++ b/crates/typst-syntax/src/parser.rs @@ -1102,13 +1102,17 @@ fn expr_with_paren(p: &mut Parser, atomic: bool) { if p.at(SyntaxKind::Arrow) { p.restore(checkpoint); params(p); - p.assert(SyntaxKind::Arrow); + if !p.expect(SyntaxKind::Arrow) { + return; + } code_expr(p); p.wrap(m, SyntaxKind::Closure); } else if p.at(SyntaxKind::Eq) && kind != SyntaxKind::Parenthesized { p.restore(checkpoint); destructuring_or_parenthesized(p, true, &mut HashSet::new()); - p.assert(SyntaxKind::Eq); + if !p.expect(SyntaxKind::Eq) { + return; + } code_expr(p); p.wrap(m, SyntaxKind::DestructAssignment); } else { diff --git a/tests/suite/syntax/bugs.typ b/tests/suite/syntax/bugs.typ new file mode 100644 index 00000000..53c41b01 --- /dev/null +++ b/tests/suite/syntax/bugs.typ @@ -0,0 +1,21 @@ +--- issue-4571-panic-when-compiling-invalid-file --- +// Test that trying to parse the following does not result in a panic. + +// Error: 1:9-10 unclosed delimiter +// Error: 1:22 expected pattern +// Error: 1:23-24 unexpected star +// Error: 2:1-2:2 the character `#` is not valid in code +// Error: 2:2-2:8 expected pattern, found keyword `import` +// Hint: 2:2-2:8 keyword `import` is not allowed as an identifier; try `import_` instead +// Error: 2:9-2:20 expected identifier, found string +// Error: 3:1-3:2 the character `#` is not valid in code +// Error: 3:2-3:5 expected pattern, found keyword `let` +// Hint: 3:2-3:5 keyword `let` is not allowed as an identifier; try `let_` instead +// Error: 4:3-4:4 unexpected equals sign +// Error: 4:5-4:6 unclosed delimiter +// Error: 4:6 expected equals sign +#import (hntle-clues: * +#import "/util.typ": qrlink +#let auton( +) = { +