From 904e422d36f5b2d6a96bda9ac4b38b2b0a8c245a Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Sat, 22 Oct 2022 11:14:02 +0000 Subject: [PATCH] Fix Regex literal parsing in MemberExpression (#2328) This Pull Request fixes/closes #2327 It changes the following: - set_goal(RegExp) for PrimaryExpression parsing --- .../expression/left_hand_side/arguments.rs | 3 +- .../expression/left_hand_side/member.rs | 6 ++- .../src/syntax/parser/expression/tests.rs | 54 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/boa_engine/src/syntax/parser/expression/left_hand_side/arguments.rs b/boa_engine/src/syntax/parser/expression/left_hand_side/arguments.rs index 9cd66f8d51..b6547c92c5 100644 --- a/boa_engine/src/syntax/parser/expression/left_hand_side/arguments.rs +++ b/boa_engine/src/syntax/parser/expression/left_hand_side/arguments.rs @@ -59,6 +59,7 @@ where cursor.expect(Punctuator::OpenParen, "arguments", interner)?; let mut args = Vec::new(); loop { + cursor.set_goal(InputElement::RegExp); let next_token = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd)?; match next_token.kind() { @@ -102,13 +103,13 @@ where .into(), ); } else { - cursor.set_goal(InputElement::RegExp); args.push( AssignmentExpression::new(None, true, self.allow_yield, self.allow_await) .parse(cursor, interner)?, ); } } + cursor.set_goal(InputElement::Div); Ok(args.into_boxed_slice()) } } diff --git a/boa_engine/src/syntax/parser/expression/left_hand_side/member.rs b/boa_engine/src/syntax/parser/expression/left_hand_side/member.rs index 3fb26e6063..ad7e3bd9ee 100644 --- a/boa_engine/src/syntax/parser/expression/left_hand_side/member.rs +++ b/boa_engine/src/syntax/parser/expression/left_hand_side/member.rs @@ -17,7 +17,7 @@ use crate::syntax::{ }, Keyword, Punctuator, }, - lexer::TokenKind, + lexer::{InputElement, TokenKind}, parser::{ expression::{ left_hand_side::template::TaggedTemplateLiteral, primary::PrimaryExpression, Expression, @@ -67,6 +67,8 @@ where fn parse(self, cursor: &mut Cursor, interner: &mut Interner) -> ParseResult { let _timer = Profiler::global().start_event("MemberExpression", "Parsing"); + cursor.set_goal(InputElement::RegExp); + let token = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd)?; let mut lhs = match token.kind() { TokenKind::Keyword((Keyword::New | Keyword::Super, true)) => { @@ -160,6 +162,8 @@ where .parse(cursor, interner)?, }; + cursor.set_goal(InputElement::TemplateTail); + while let Some(tok) = cursor.peek(0, interner)? { match tok.kind() { TokenKind::Punctuator(Punctuator::Dot) => { diff --git a/boa_engine/src/syntax/parser/expression/tests.rs b/boa_engine/src/syntax/parser/expression/tests.rs index a8c5a10524..0602184b03 100644 --- a/boa_engine/src/syntax/parser/expression/tests.rs +++ b/boa_engine/src/syntax/parser/expression/tests.rs @@ -119,6 +119,60 @@ fn check_numeric_operations() { interner, ); + let mut interner = Interner::default(); + check_parser( + "fn(/=/);", + vec![Statement::Expression(Expression::from(Call::new( + Identifier::new(interner.get_or_intern_static("fn", utf16!("fn"))).into(), + vec![New::from(Call::new( + Identifier::new(Sym::REGEXP).into(), + vec![ + Literal::from(interner.get_or_intern_static("=", utf16!("="))).into(), + Literal::from(Sym::EMPTY_STRING).into(), + ] + .into(), + )) + .into()] + .into(), + ))) + .into()], + interner, + ); + + let mut interner = Interner::default(); + check_parser( + "fn(a / b);", + vec![Statement::Expression(Expression::from(Call::new( + Identifier::new(interner.get_or_intern_static("fn", utf16!("fn"))).into(), + vec![Expression::from(Binary::new( + ArithmeticOp::Div.into(), + Identifier::new(interner.get_or_intern_static("a", utf16!("a"))).into(), + Identifier::new(interner.get_or_intern_static("b", utf16!("b"))).into(), + )) + .into()] + .into(), + ))) + .into()], + interner, + ); + + let mut interner = Interner::default(); + check_parser( + "fn(a) / b;", + vec![Statement::Expression(Expression::from(Binary::new( + ArithmeticOp::Div.into(), + Call::new( + Identifier::new(interner.get_or_intern_static("fn", utf16!("fn"))).into(), + vec![Identifier::new(interner.get_or_intern_static("a", utf16!("a"))).into()] + .into(), + ) + .into(), + Identifier::new(interner.get_or_intern_static("b", utf16!("b"))).into(), + ))) + .into()], + interner, + ); + let mut interner = Interner::default(); check_parser( "a * b",