Fix panic on trailing backslash in string (fixes #551)
This commit is contained in:
parent
37fc231761
commit
f0d4f40dcf
2 changed files with 19 additions and 6 deletions
|
@ -166,7 +166,7 @@ impl<'s> Lexer<'s> {
|
|||
|
||||
let tok_str = &self.source[self.pos..self.pos + len];
|
||||
let old_pos = self.pos;
|
||||
self.advance_by(len);
|
||||
self.advance_by(len)?;
|
||||
match LEXER_FNS[i](tok_str.to_string()) {
|
||||
Token::Skip | Token::Comment => {}
|
||||
token => {
|
||||
|
@ -177,11 +177,17 @@ impl<'s> Lexer<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
fn advance_by(&mut self, n: usize) {
|
||||
/// Advance position by the given number of characters, respecting char boundaries. Returns `None` when n exceeds the source length
|
||||
#[must_use]
|
||||
fn advance_by(&mut self, n: usize) -> Option<()> {
|
||||
if self.pos + n > self.source.len() {
|
||||
return None;
|
||||
}
|
||||
self.pos += n;
|
||||
while self.pos < self.source.len() && !self.source.is_char_boundary(self.pos) {
|
||||
self.pos += 1;
|
||||
}
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn advance_until_one_of<'a>(&mut self, pat: &[&'a str]) -> Option<&'a str> {
|
||||
|
@ -190,10 +196,10 @@ impl<'s> Lexer<'s> {
|
|||
if remaining.is_empty() {
|
||||
return None;
|
||||
} else if let Some(matched) = pat.iter().find(|&&p| remaining.starts_with(p)) {
|
||||
self.advance_by(matched.len());
|
||||
self.advance_by(matched.len())?;
|
||||
return Some(matched);
|
||||
} else {
|
||||
self.advance_by(1);
|
||||
self.advance_by(1)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +209,7 @@ impl<'s> Lexer<'s> {
|
|||
pattern.push("\\");
|
||||
match self.advance_until_one_of(pattern.as_slice()) {
|
||||
Some("\\") => {
|
||||
self.advance_by(1);
|
||||
self.advance_by(1)?;
|
||||
self.advance_until_unescaped_one_of(pat)
|
||||
}
|
||||
result => result,
|
||||
|
@ -213,7 +219,7 @@ impl<'s> Lexer<'s> {
|
|||
pub fn string_lit(&mut self) -> Option<Result<Sp<Vec<Sp<StrLitSegment>>>, LexicalError>> {
|
||||
let quote = self.remaining().chars().next()?.to_string();
|
||||
let str_lit_start = self.pos;
|
||||
self.advance_by(quote.len());
|
||||
self.advance_by(quote.len())?;
|
||||
|
||||
let mut elements = Vec::new();
|
||||
let mut in_string_lit = true;
|
||||
|
@ -308,6 +314,7 @@ mod test {
|
|||
snapshot_string! {
|
||||
basic => v!(r#"bar "foo""#),
|
||||
digit => v!(r#"12"#),
|
||||
quote_backslash_eof => v!(r#""\"#),
|
||||
number_in_ident => v!(r#"foo_1_bar"#),
|
||||
interpolation_1 => v!(r#" "foo ${2 * 2} bar" "#),
|
||||
interpolation_nested => v!(r#" "foo ${(2 * 2) + "${5 + 5}"} bar" "#),
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
source: crates/simplexpr/src/parser/lexer.rs
|
||||
assertion_line: 313
|
||||
expression: "v!(r#\"\"\\\"#)"
|
||||
---
|
||||
|
Loading…
Add table
Reference in a new issue