From 339b8621d583163ebfdfadebf7af479ad375e298 Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Sat, 5 Feb 2022 23:10:27 +0100 Subject: [PATCH 1/3] Fixed #1768 --- boa/src/syntax/parser/cursor/buffered_lexer/mod.rs | 10 ++++++---- boa/src/syntax/parser/expression/assignment/mod.rs | 12 ++++++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs b/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs index 573891e16c2..a52bbb9a6c7 100644 --- a/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs +++ b/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs @@ -17,12 +17,12 @@ const MAX_PEEK_SKIP: usize = 3; /// The fixed size of the buffer used for storing values that are peeked ahead. /// /// The size is calculated for a worst case scenario, where we want to peek `MAX_PEEK_SKIP` tokens -/// skipping line terminators: +/// skipping line terminators, and the stream ends just after: /// ```text -/// [\n, B, \n, C, \n, D, \n, E, \n, F] -/// 0 0 1 1 2 2 3 3 4 4 +/// [\n, B, \n, C, \n, D, \n, E, \n, F, None] +/// 0 0 1 1 2 2 3 3 4 4 5 /// ``` -const PEEK_BUF_SIZE: usize = (MAX_PEEK_SKIP + 1) * 2; +const PEEK_BUF_SIZE: usize = (MAX_PEEK_SKIP + 1) * 2 + 1; #[derive(Debug)] pub(super) struct BufferedLexer { @@ -49,6 +49,7 @@ where None::, None::, None::, + None::, ], read_index: 0, write_index: 0, @@ -152,6 +153,7 @@ where self.read_index, self.write_index, "we reached the read index with the write index" ); + debug_assert!( self.read_index < PEEK_BUF_SIZE, "read index went out of bounds" diff --git a/boa/src/syntax/parser/expression/assignment/mod.rs b/boa/src/syntax/parser/expression/assignment/mod.rs index 81b67ffd9d5..f1611b991e4 100644 --- a/boa/src/syntax/parser/expression/assignment/mod.rs +++ b/boa/src/syntax/parser/expression/assignment/mod.rs @@ -155,8 +155,13 @@ where TokenKind::Punctuator(Punctuator::CloseParen) => { // Need to check if the token after the close paren is an arrow, if so then this is an ArrowFunction // otherwise it is an expression of the form (b). - if let Some(t) = cursor.peek(3, interner)? { - if t.kind() == &TokenKind::Punctuator(Punctuator::Arrow) + #[allow(clippy::match_same_arms)] + match cursor.peek(3, interner) { + Ok(Some(t)) + if t.kind() + == &TokenKind::Punctuator( + Punctuator::Arrow, + ) => { return ArrowFunction::new( self.allow_in, @@ -166,6 +171,9 @@ where .parse(cursor, interner) .map(Node::ArrowFunctionDecl); } + Err(ParseError::AbruptEnd) => {} + Err(e) => return Err(e), + _ => {} } } _ => {} From 5663342046dca1adece4d9fcc465e75ccba47280 Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Sat, 5 Feb 2022 23:28:52 +0100 Subject: [PATCH 2/3] Removed unnecesary changes --- .../syntax/parser/cursor/buffered_lexer/mod.rs | 1 - .../syntax/parser/expression/assignment/mod.rs | 17 +++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs b/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs index a52bbb9a6c7..66a5b51307a 100644 --- a/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs +++ b/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs @@ -153,7 +153,6 @@ where self.read_index, self.write_index, "we reached the read index with the write index" ); - debug_assert!( self.read_index < PEEK_BUF_SIZE, "read index went out of bounds" diff --git a/boa/src/syntax/parser/expression/assignment/mod.rs b/boa/src/syntax/parser/expression/assignment/mod.rs index f1611b991e4..af4bb2eaca1 100644 --- a/boa/src/syntax/parser/expression/assignment/mod.rs +++ b/boa/src/syntax/parser/expression/assignment/mod.rs @@ -153,15 +153,11 @@ where .map(Node::ArrowFunctionDecl); } TokenKind::Punctuator(Punctuator::CloseParen) => { - // Need to check if the token after the close paren is an arrow, if so then this is an ArrowFunction - // otherwise it is an expression of the form (b). - #[allow(clippy::match_same_arms)] - match cursor.peek(3, interner) { - Ok(Some(t)) - if t.kind() - == &TokenKind::Punctuator( - Punctuator::Arrow, - ) => + // Need to check if the token after the close paren is an + // arrow, if so then this is an ArrowFunction otherwise it + // is an expression of the form (b). + if let Some(t) = cursor.peek(3, interner)? { + if t.kind() == &TokenKind::Punctuator(Punctuator::Arrow) { return ArrowFunction::new( self.allow_in, @@ -171,9 +167,6 @@ where .parse(cursor, interner) .map(Node::ArrowFunctionDecl); } - Err(ParseError::AbruptEnd) => {} - Err(e) => return Err(e), - _ => {} } } _ => {} From 7aa59ea643254b4961eaaa81f339b144e305df54 Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Sat, 5 Feb 2022 23:39:01 +0100 Subject: [PATCH 3/3] Added test for peeking issue --- boa/src/syntax/parser/cursor/buffered_lexer/tests.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boa/src/syntax/parser/cursor/buffered_lexer/tests.rs b/boa/src/syntax/parser/cursor/buffered_lexer/tests.rs index 57e0fd53dcd..b2a301736d9 100644 --- a/boa/src/syntax/parser/cursor/buffered_lexer/tests.rs +++ b/boa/src/syntax/parser/cursor/buffered_lexer/tests.rs @@ -278,3 +278,11 @@ fn skip_peeked_terminators() { // End of stream assert!(cur.peek(2, true, &mut interner).unwrap().is_none()); } + +#[test] +fn issue_1768() { + let mut cur = BufferedLexer::from(&b"\n(\nx\n)\n"[..]); + let mut interner = Interner::default(); + + assert!(cur.peek(3, true, &mut interner).unwrap().is_none()); +}