diff --git a/core/parser/src/lexer/mod.rs b/core/parser/src/lexer/mod.rs index 3e493ea800f..fe5edb18f42 100644 --- a/core/parser/src/lexer/mod.rs +++ b/core/parser/src/lexer/mod.rs @@ -401,6 +401,11 @@ impl Lexer { pub(super) fn take_source(&mut self) -> boa_ast::SourceText { self.cursor.take_source() } + + /// Gets the current linear position of the lexer. + pub(crate) fn linear_pos(&self) -> boa_ast::LinearPosition { + self.cursor.linear_pos() + } } impl<'a> From<&'a [u8]> for Lexer> { diff --git a/core/parser/src/parser/cursor/buffered_lexer/mod.rs b/core/parser/src/parser/cursor/buffered_lexer/mod.rs index 67ba7aee596..ee84acfe535 100644 --- a/core/parser/src/parser/cursor/buffered_lexer/mod.rs +++ b/core/parser/src/parser/cursor/buffered_lexer/mod.rs @@ -133,10 +133,12 @@ where ); let previous_index = self.write_index.checked_sub(1).unwrap_or(PEEK_BUF_SIZE - 1); + let is_start = self.lexer.linear_pos().pos() == 0; + let is_line_terminator = self.peeked[previous_index] + .as_ref() + .is_some_and(|token| token.kind() == &TokenKind::LineTerminator); - if let Some(ref token) = self.peeked[previous_index] - && token.kind() == &TokenKind::LineTerminator - { + if is_start || is_line_terminator { // We don't want to have multiple contiguous line terminators in the buffer, since // they have no meaning. let next = loop { diff --git a/core/parser/src/parser/cursor/buffered_lexer/tests.rs b/core/parser/src/parser/cursor/buffered_lexer/tests.rs index 7dc8c58ef5b..66c69886a75 100644 --- a/core/parser/src/parser/cursor/buffered_lexer/tests.rs +++ b/core/parser/src/parser/cursor/buffered_lexer/tests.rs @@ -287,3 +287,34 @@ fn issue_1768() { assert!(cur.peek(3, true, interner).unwrap().is_none()); } + +#[test] +#[cfg(feature = "annex-b")] +fn html_close_comment_first_line() { + let mut cur = BufferedLexer::from(&b"--> this is a comment\nthrow"[..]); + let interner = &mut Interner::default(); + + assert_eq!( + *cur.next(false, interner) + .unwrap() + .expect("Some value expected") + .kind(), + TokenKind::Keyword((boa_ast::Keyword::Throw, false)) + ); +} + +#[test] +#[cfg(feature = "annex-b")] +fn html_close_comment_first_line_with_spaces_and_comments() { + let mut cur = + BufferedLexer::from(&b" /* comment */ /*another*/--> this is a comment\nthrow"[..]); + let interner = &mut Interner::default(); + + assert_eq!( + *cur.next(false, interner) + .unwrap() + .expect("Some value expected") + .kind(), + TokenKind::Keyword((boa_ast::Keyword::Throw, false)) + ); +} diff --git a/tests/tester/src/exec/mod.rs b/tests/tester/src/exec/mod.rs index 62c0afaf5ad..fa78ffc9f10 100644 --- a/tests/tester/src/exec/mod.rs +++ b/tests/tester/src/exec/mod.rs @@ -602,6 +602,7 @@ fn is_error_type(error: &JsError, target_type: ErrorType, context: &mut Context) JsNativeErrorKind::Reference if target_type == ErrorType::ReferenceError => {} JsNativeErrorKind::Range if target_type == ErrorType::RangeError => {} JsNativeErrorKind::Type if target_type == ErrorType::TypeError => {} + JsNativeErrorKind::Eval if target_type == ErrorType::EvalError => {} _ => return false, } true