Panic when parsing fuzzed code
5225225 opened this issue · 4 comments
Describe the bug
The code should not panic.
To Reproduce
fn main() {
let data = b"\n(\nx\n)\n";
drop(boa::parse(data, true));
}
Expected behavior
It shouldn't panic, and it should parse correctly (as whatever it's meant to parse as, not sure.)
Build environment:
- OS: Arch Linux
- Target triple:
x86_64-unknown-linux-gnu
(I think, couldn't find how to print it and I don't think it's terribly important here) - Rustc version:
rustc 1.59.0-nightly (cfa3fe5af 2021-12-31)
One question, though. Why are you calling drop()
on the parsed result? That could cause a double drop maybe?
drop
just consumes the input. (It's not magic, and since it's not unsafe
it can't cause a double drop).
If you look at https://doc.rust-lang.org/std/mem/fn.drop.html it says it's literally defined as
pub fn drop<T>(_x: T) { }
I do it to silence the unused variable warning that you otherwise get from the Result
.
I've tried to diagnose it and I'm pretty sure it's a bug in the lexer, I think its because there is only a \n
after the closing parenthesis.
It tries to peek for a token after the )
to check if it is =>
, which would mean it is an arrow function. But in this case there is no other token ahead of it and while trying to fill the lexer's buffer something goes wrong.
The BufferedLexer
's write_index is "overflowing"
peeked
contains ['\n', '(', '\n', 'x', '\n', ')', '\n']
The line trying to peek is here
boa/boa/src/syntax/parser/expression/assignment/mod.rs
Lines 149 to 153 in d831ff3
I have the peeking visualized below:
\n ( \n x \n ) \n ?
0 0 1 1 2 2 3 3
This seems to be the max size we expected, the ?
becomes None
during the fill
function, but right afterwards it increments write_index
, which goes back to 0 and it fails the assertion:
boa/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs
Lines 136 to 141 in d831ff3