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 tok_str = &self.source[self.pos..self.pos + len];
|
||||||
let old_pos = self.pos;
|
let old_pos = self.pos;
|
||||||
self.advance_by(len);
|
self.advance_by(len)?;
|
||||||
match LEXER_FNS[i](tok_str.to_string()) {
|
match LEXER_FNS[i](tok_str.to_string()) {
|
||||||
Token::Skip | Token::Comment => {}
|
Token::Skip | Token::Comment => {}
|
||||||
token => {
|
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;
|
self.pos += n;
|
||||||
while self.pos < self.source.len() && !self.source.is_char_boundary(self.pos) {
|
while self.pos < self.source.len() && !self.source.is_char_boundary(self.pos) {
|
||||||
self.pos += 1;
|
self.pos += 1;
|
||||||
}
|
}
|
||||||
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn advance_until_one_of<'a>(&mut self, pat: &[&'a str]) -> Option<&'a str> {
|
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() {
|
if remaining.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
} else if let Some(matched) = pat.iter().find(|&&p| remaining.starts_with(p)) {
|
} 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);
|
return Some(matched);
|
||||||
} else {
|
} else {
|
||||||
self.advance_by(1);
|
self.advance_by(1)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +209,7 @@ impl<'s> Lexer<'s> {
|
||||||
pattern.push("\\");
|
pattern.push("\\");
|
||||||
match self.advance_until_one_of(pattern.as_slice()) {
|
match self.advance_until_one_of(pattern.as_slice()) {
|
||||||
Some("\\") => {
|
Some("\\") => {
|
||||||
self.advance_by(1);
|
self.advance_by(1)?;
|
||||||
self.advance_until_unescaped_one_of(pat)
|
self.advance_until_unescaped_one_of(pat)
|
||||||
}
|
}
|
||||||
result => result,
|
result => result,
|
||||||
|
@ -213,7 +219,7 @@ impl<'s> Lexer<'s> {
|
||||||
pub fn string_lit(&mut self) -> Option<Result<Sp<Vec<Sp<StrLitSegment>>>, LexicalError>> {
|
pub fn string_lit(&mut self) -> Option<Result<Sp<Vec<Sp<StrLitSegment>>>, LexicalError>> {
|
||||||
let quote = self.remaining().chars().next()?.to_string();
|
let quote = self.remaining().chars().next()?.to_string();
|
||||||
let str_lit_start = self.pos;
|
let str_lit_start = self.pos;
|
||||||
self.advance_by(quote.len());
|
self.advance_by(quote.len())?;
|
||||||
|
|
||||||
let mut elements = Vec::new();
|
let mut elements = Vec::new();
|
||||||
let mut in_string_lit = true;
|
let mut in_string_lit = true;
|
||||||
|
@ -308,6 +314,7 @@ mod test {
|
||||||
snapshot_string! {
|
snapshot_string! {
|
||||||
basic => v!(r#"bar "foo""#),
|
basic => v!(r#"bar "foo""#),
|
||||||
digit => v!(r#"12"#),
|
digit => v!(r#"12"#),
|
||||||
|
quote_backslash_eof => v!(r#""\"#),
|
||||||
number_in_ident => v!(r#"foo_1_bar"#),
|
number_in_ident => v!(r#"foo_1_bar"#),
|
||||||
interpolation_1 => v!(r#" "foo ${2 * 2} bar" "#),
|
interpolation_1 => v!(r#" "foo ${2 * 2} bar" "#),
|
||||||
interpolation_nested => v!(r#" "foo ${(2 * 2) + "${5 + 5}"} 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