Fix tokenizer crash

This would crash from the highlighter for something like

`PATH={$PATH[echo " "`

The underlying cause is that we use "char_at" which panics on
overread.

So instead this implements try_char_at and then just returns None.
This commit is contained in:
Fabian Boehm
2024-01-09 19:12:16 +01:00
parent f7c9538fb0
commit b82dad0160
3 changed files with 16 additions and 8 deletions

View File

@@ -769,16 +769,9 @@ pub fn quote_end(s: &wstr, mut pos: usize, quote: char) -> Option<usize> {
loop {
pos += 1;
if pos == s.len() {
return None;
}
let c = s.char_at(pos);
let c = s.try_char_at(pos)?;
if c == '\\' {
pos += 1;
if pos == s.len() {
return None;
}
} else if c == quote ||
// Command substitutions also end a double quoted string. This is how we
// support command substitutions inside double quotes.

View File

@@ -222,6 +222,18 @@ fn char_at(&self, index: usize) -> char {
}
}
/// Return the char at an index.
/// If the index is equal to the length, return '\0'.
/// If the index exceeds the length, return None.
fn try_char_at(&self, index: usize) -> Option<char> {
let chars = self.as_char_slice();
match index {
_ if index == chars.len() => Some('\0'),
_ if index > chars.len() => None,
_ => Some(chars[index]),
}
}
/// \return an iterator over substrings, split by a given char.
/// The split char is not included in the substrings.
fn split(&self, c: char) -> WStrCharSplitIter {

View File

@@ -432,3 +432,6 @@ echo 'begin
echo 'multiline-\\
-word' | $fish_indent --check
echo $status #CHECK: 0
echo 'PATH={$PATH[echo " "' | $fish_indent --ansi
# CHECK: PATH={$PATH[echo " "