From 382f7d31fdcfd0627004d240fd3efca5f5d23cc7 Mon Sep 17 00:00:00 2001 From: raskad <32105367+raskad@users.noreply.github.com> Date: Wed, 4 Jan 2023 20:38:56 +0100 Subject: [PATCH 1/2] Add early errors for 'eval' or 'arguments' in parameters --- boa_ast/src/operations.rs | 11 +++ .../primary/async_function_expression/mod.rs | 72 +++++++++++-------- .../primary/async_generator_expression/mod.rs | 61 ++++++++++------ .../primary/function_expression/mod.rs | 49 ++++++++----- .../primary/generator_expression/mod.rs | 62 ++++++++++------ .../src/parser/expression/primary/mod.rs | 2 +- .../statement/declaration/hoistable/mod.rs | 41 ++++++----- 7 files changed, 192 insertions(+), 106 deletions(-) diff --git a/boa_ast/src/operations.rs b/boa_ast/src/operations.rs index e2aa9141ce7..7919d76e122 100644 --- a/boa_ast/src/operations.rs +++ b/boa_ast/src/operations.rs @@ -47,6 +47,8 @@ pub enum ContainsSymbol { This, /// A method definition. MethodDefinition, + /// The BindingIdentifier "eval" or "arguments". + EvalOrArguments, } /// Returns `true` if the node contains the given symbol. @@ -66,6 +68,15 @@ where impl<'ast> Visitor<'ast> for ContainsVisitor { type BreakTy = (); + fn visit_identifier(&mut self, node: &'ast Identifier) -> ControlFlow { + if self.0 == ContainsSymbol::EvalOrArguments + && (node.sym() == Sym::EVAL || node.sym() == Sym::ARGUMENTS) + { + return ControlFlow::Break(()); + } + ControlFlow::Continue(()) + } + fn visit_function(&mut self, _: &'ast Function) -> ControlFlow { ControlFlow::Continue(()) } diff --git a/boa_parser/src/parser/expression/primary/async_function_expression/mod.rs b/boa_parser/src/parser/expression/primary/async_function_expression/mod.rs index 12d8d7f40d2..f443396e4dc 100644 --- a/boa_parser/src/parser/expression/primary/async_function_expression/mod.rs +++ b/boa_parser/src/parser/expression/primary/async_function_expression/mod.rs @@ -6,7 +6,7 @@ use crate::{ parser::{ expression::BindingIdentifier, function::{FormalParameters, FunctionBody}, - name_in_lexically_declared_names, AllowYield, Cursor, OrAbrupt, ParseResult, TokenParser, + name_in_lexically_declared_names, Cursor, OrAbrupt, ParseResult, TokenParser, }, Error, }; @@ -14,7 +14,7 @@ use boa_ast::{ expression::Identifier, function::AsyncFunction, operations::{bound_names, contains, top_level_lexically_declared_names, ContainsSymbol}, - Keyword, Position, Punctuator, + Keyword, Punctuator, }; use boa_interner::{Interner, Sym}; use boa_profiler::Profiler; @@ -31,20 +31,15 @@ use std::io::Read; #[derive(Debug, Clone, Copy)] pub(super) struct AsyncFunctionExpression { name: Option, - allow_yield: AllowYield, } impl AsyncFunctionExpression { /// Creates a new `AsyncFunctionExpression` parser. - pub(super) fn new(name: N, allow_yield: Y) -> Self + pub(super) fn new(name: N) -> Self where N: Into>, - Y: Into, { - Self { - name: name.into(), - allow_yield: allow_yield.into(), - } + Self { name: name.into() } } } @@ -63,26 +58,20 @@ where interner, )?; - let (name, has_binding_identifier) = match cursor.peek(0, interner).or_abrupt()?.kind() { - TokenKind::Punctuator(Punctuator::OpenParen) => (self.name, false), - _ => ( - Some(BindingIdentifier::new(self.allow_yield, true).parse(cursor, interner)?), - true, - ), - }; - - // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, - // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - if let Some(name) = name { - if cursor.strict_mode() && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) { - return Err(Error::lex(LexError::Syntax( - "Unexpected eval or arguments in strict mode".into(), - cursor - .peek(0, interner)? - .map_or_else(|| Position::new(1, 1), |token| token.span().end()), - ))); + let token = cursor.peek(0, interner).or_abrupt()?; + let (name, name_span) = match token.kind() { + TokenKind::Identifier(_) + | TokenKind::Keyword(( + Keyword::Yield | Keyword::Await | Keyword::Async | Keyword::Of, + _, + )) => { + let span = token.span(); + let name = BindingIdentifier::new(false, true).parse(cursor, interner)?; + + (Some(name), span) } - } + _ => (None, token.span()), + }; let params_start_position = cursor .expect(Punctuator::OpenParen, "async function expression", interner)? @@ -124,6 +113,26 @@ where ))); } + // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, + // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". + if (cursor.strict_mode() || body.strict()) + && [Some(Sym::EVAL), Some(Sym::ARGUMENTS)].contains(&name.map(Identifier::sym)) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } + + // Catch early error for BindingIdentifier, because strictness of the functions body is also + // relevant for the function parameters. + if body.strict() && contains(¶ms, ContainsSymbol::EvalOrArguments) { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + params_start_position, + ))); + } + // It is a Syntax Error if any element of the BoundNames of FormalParameters // also occurs in the LexicallyDeclaredNames of FunctionBody. // https://tc39.es/ecma262/#sec-function-definitions-static-semantics-early-errors @@ -133,7 +142,12 @@ where params_start_position, )?; - let function = AsyncFunction::new(name, params, body, has_binding_identifier); + let function = AsyncFunction::new( + if name.is_some() { name } else { self.name }, + params, + body, + name.is_some(), + ); if contains(&function, ContainsSymbol::Super) { return Err(Error::lex(LexError::Syntax( diff --git a/boa_parser/src/parser/expression/primary/async_generator_expression/mod.rs b/boa_parser/src/parser/expression/primary/async_generator_expression/mod.rs index 660452da602..e79b692ad25 100644 --- a/boa_parser/src/parser/expression/primary/async_generator_expression/mod.rs +++ b/boa_parser/src/parser/expression/primary/async_generator_expression/mod.rs @@ -23,7 +23,7 @@ use boa_ast::{ expression::Identifier, function::AsyncGenerator, operations::{bound_names, contains, top_level_lexically_declared_names, ContainsSymbol}, - Keyword, Position, Punctuator, + Keyword, Punctuator, }; use boa_interner::{Interner, Sym}; use boa_profiler::Profiler; @@ -72,26 +72,20 @@ where interner, )?; - let (name, has_binding_identifier) = match cursor.peek(0, interner).or_abrupt()?.kind() { - TokenKind::Punctuator(Punctuator::OpenParen) => (self.name, false), - _ => ( - Some(BindingIdentifier::new(true, true).parse(cursor, interner)?), - true, - ), - }; - - // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict - // mode code, it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - if let Some(name) = name { - if cursor.strict_mode() && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) { - return Err(Error::lex(LexError::Syntax( - "Unexpected eval or arguments in strict mode".into(), - cursor - .peek(0, interner)? - .map_or_else(|| Position::new(1, 1), |token| token.span().end()), - ))); + let token = cursor.peek(0, interner).or_abrupt()?; + let (name, name_span) = match token.kind() { + TokenKind::Identifier(_) + | TokenKind::Keyword(( + Keyword::Yield | Keyword::Await | Keyword::Async | Keyword::Of, + _, + )) => { + let span = token.span(); + let name = BindingIdentifier::new(true, true).parse(cursor, interner)?; + + (Some(name), span) } - } + _ => (None, token.span()), + }; let params_start_position = cursor .expect( @@ -157,6 +151,26 @@ where ))); } + // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, + // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". + if (cursor.strict_mode() || body.strict()) + && [Some(Sym::EVAL), Some(Sym::ARGUMENTS)].contains(&name.map(Identifier::sym)) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } + + // Catch early error for BindingIdentifier, because strictness of the functions body is also + // relevant for the function parameters. + if body.strict() && contains(¶ms, ContainsSymbol::EvalOrArguments) { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + params_start_position, + ))); + } + // It is a Syntax Error if any element of the BoundNames of FormalParameters // also occurs in the LexicallyDeclaredNames of FunctionBody. name_in_lexically_declared_names( @@ -165,7 +179,12 @@ where params_start_position, )?; - let function = AsyncGenerator::new(name, params, body, has_binding_identifier); + let function = AsyncGenerator::new( + if name.is_some() { name } else { self.name }, + params, + body, + name.is_some(), + ); if contains(&function, ContainsSymbol::Super) { return Err(Error::lex(LexError::Syntax( diff --git a/boa_parser/src/parser/expression/primary/function_expression/mod.rs b/boa_parser/src/parser/expression/primary/function_expression/mod.rs index f7e7e554df7..d9d98150f7a 100644 --- a/boa_parser/src/parser/expression/primary/function_expression/mod.rs +++ b/boa_parser/src/parser/expression/primary/function_expression/mod.rs @@ -23,7 +23,7 @@ use boa_ast::{ expression::Identifier, function::Function, operations::{bound_names, contains, top_level_lexically_declared_names, ContainsSymbol}, - Keyword, Position, Punctuator, + Keyword, Punctuator, }; use boa_interner::{Interner, Sym}; use boa_profiler::Profiler; @@ -61,28 +61,19 @@ where fn parse(self, cursor: &mut Cursor, interner: &mut Interner) -> ParseResult { let _timer = Profiler::global().start_event("FunctionExpression", "Parsing"); - let (name, has_binding_identifier) = match cursor.peek(0, interner).or_abrupt()?.kind() { + let token = cursor.peek(0, interner).or_abrupt()?; + let (name, name_span) = match token.kind() { TokenKind::Identifier(_) | TokenKind::Keyword(( Keyword::Yield | Keyword::Await | Keyword::Async | Keyword::Of, _, )) => { + let span = token.span(); let name = BindingIdentifier::new(false, false).parse(cursor, interner)?; - // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, - // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - if cursor.strict_mode() && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) { - return Err(Error::lex(LexError::Syntax( - "Unexpected eval or arguments in strict mode".into(), - cursor - .peek(0, interner)? - .map_or_else(|| Position::new(1, 1), |token| token.span().end()), - ))); - } - - (Some(name), true) + (Some(name), span) } - _ => (self.name, false), + _ => (None, token.span()), }; let params_start_position = cursor @@ -117,6 +108,26 @@ where ))); } + // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, + // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". + if (cursor.strict_mode() || body.strict()) + && [Some(Sym::EVAL), Some(Sym::ARGUMENTS)].contains(&name.map(Identifier::sym)) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } + + // Catch early error for BindingIdentifier, because strictness of the functions body is also + // relevant for the function parameters. + if body.strict() && contains(¶ms, ContainsSymbol::EvalOrArguments) { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + params_start_position, + ))); + } + // It is a Syntax Error if any element of the BoundNames of FormalParameters // also occurs in the LexicallyDeclaredNames of FunctionBody. // https://tc39.es/ecma262/#sec-function-definitions-static-semantics-early-errors @@ -126,8 +137,12 @@ where params_start_position, )?; - let function = - Function::new_with_binding_identifier(name, params, body, has_binding_identifier); + let function = Function::new_with_binding_identifier( + if name.is_some() { name } else { self.name }, + params, + body, + name.is_some(), + ); if contains(&function, ContainsSymbol::Super) { return Err(Error::lex(LexError::Syntax( diff --git a/boa_parser/src/parser/expression/primary/generator_expression/mod.rs b/boa_parser/src/parser/expression/primary/generator_expression/mod.rs index 8f9c920afb8..a8683e03142 100644 --- a/boa_parser/src/parser/expression/primary/generator_expression/mod.rs +++ b/boa_parser/src/parser/expression/primary/generator_expression/mod.rs @@ -23,7 +23,7 @@ use boa_ast::{ expression::Identifier, function::Generator, operations::{bound_names, contains, top_level_lexically_declared_names, ContainsSymbol}, - Position, Punctuator, + Keyword, Punctuator, }; use boa_interner::{Interner, Sym}; use boa_profiler::Profiler; @@ -67,27 +67,20 @@ where interner, )?; - let (name, has_binding_identifier) = match cursor.peek(0, interner).or_abrupt()?.kind() { - TokenKind::Punctuator(Punctuator::OpenParen) => (self.name, false), - _ => ( - Some(BindingIdentifier::new(true, false).parse(cursor, interner)?), - true, - ), - }; - - // If BindingIdentifier is present and the source text matched by BindingIdentifier is strict mode code, - // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - // https://tc39.es/ecma262/#sec-generator-function-definitions-static-semantics-early-errors - if let Some(name) = name { - if cursor.strict_mode() && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) { - return Err(Error::lex(LexError::Syntax( - "Unexpected eval or arguments in strict mode".into(), - cursor - .peek(0, interner)? - .map_or_else(|| Position::new(1, 1), |token| token.span().end()), - ))); + let token = cursor.peek(0, interner).or_abrupt()?; + let (name, name_span) = match token.kind() { + TokenKind::Identifier(_) + | TokenKind::Keyword(( + Keyword::Yield | Keyword::Await | Keyword::Async | Keyword::Of, + _, + )) => { + let span = token.span(); + let name = BindingIdentifier::new(true, false).parse(cursor, interner)?; + + (Some(name), span) } - } + _ => (None, token.span()), + }; let params_start_position = cursor .expect(Punctuator::OpenParen, "generator expression", interner)? @@ -123,6 +116,26 @@ where ))); } + // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, + // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". + if (cursor.strict_mode() || body.strict()) + && [Some(Sym::EVAL), Some(Sym::ARGUMENTS)].contains(&name.map(Identifier::sym)) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } + + // Catch early error for BindingIdentifier, because strictness of the functions body is also + // relevant for the function parameters. + if body.strict() && contains(¶ms, ContainsSymbol::EvalOrArguments) { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + params_start_position, + ))); + } + // It is a Syntax Error if any element of the BoundNames of FormalParameters // also occurs in the LexicallyDeclaredNames of GeneratorBody. // https://tc39.es/ecma262/#sec-generator-function-definitions-static-semantics-early-errors @@ -141,7 +154,12 @@ where ))); } - let function = Generator::new(name, params, body, has_binding_identifier); + let function = Generator::new( + if name.is_some() { name } else { self.name }, + params, + body, + name.is_some(), + ); if contains(&function, ContainsSymbol::Super) { return Err(Error::lex(LexError::Syntax( diff --git a/boa_parser/src/parser/expression/primary/mod.rs b/boa_parser/src/parser/expression/primary/mod.rs index 33a142dc75d..b46f4c35cbe 100644 --- a/boa_parser/src/parser/expression/primary/mod.rs +++ b/boa_parser/src/parser/expression/primary/mod.rs @@ -147,7 +147,7 @@ where .parse(cursor, interner) .map(Into::into) } - _ => AsyncFunctionExpression::new(self.name, self.allow_yield) + _ => AsyncFunctionExpression::new(self.name) .parse(cursor, interner) .map(Into::into), } diff --git a/boa_parser/src/parser/statement/declaration/hoistable/mod.rs b/boa_parser/src/parser/statement/declaration/hoistable/mod.rs index 96d15679a12..737baa9be66 100644 --- a/boa_parser/src/parser/statement/declaration/hoistable/mod.rs +++ b/boa_parser/src/parser/statement/declaration/hoistable/mod.rs @@ -34,7 +34,7 @@ use boa_ast::{ expression::Identifier, function::FormalParameterList, operations::{bound_names, contains, top_level_lexically_declared_names, ContainsSymbol}, - Declaration, Keyword, Position, Punctuator, StatementList, + Declaration, Keyword, Punctuator, StatementList, }; use boa_interner::{Interner, Sym}; use boa_profiler::Profiler; @@ -143,13 +143,14 @@ fn parse_callable_declaration( cursor: &mut Cursor, interner: &mut Interner, ) -> ParseResult<(Identifier, FormalParameterList, StatementList)> { - let next_token = cursor.peek(0, interner).or_abrupt()?; - let name = match next_token.kind() { + let token = cursor.peek(0, interner).or_abrupt()?; + let name_span = token.span(); + let name = match token.kind() { TokenKind::Punctuator(Punctuator::OpenParen) => { if !c.is_default() { return Err(Error::unexpected( - next_token.to_string(interner), - next_token.span(), + token.to_string(interner), + token.span(), c.error_context(), )); } @@ -159,17 +160,6 @@ fn parse_callable_declaration( .parse(cursor, interner)?, }; - // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, - // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - if cursor.strict_mode() && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) { - return Err(Error::lex(LexError::Syntax( - "Unexpected eval or arguments in strict mode".into(), - cursor - .peek(0, interner)? - .map_or_else(|| Position::new(1, 1), |token| token.span().end()), - ))); - } - let params_start_position = cursor .expect(Punctuator::OpenParen, c.error_context(), interner)? .span() @@ -204,6 +194,25 @@ fn parse_callable_declaration( ))); } + // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, + // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". + if (cursor.strict_mode() || body.strict()) && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } + + // Early Error for BindingIdentifier, because the strictness of the functions body is also + // relevant for the function parameters. + if body.strict() && contains(¶ms, ContainsSymbol::EvalOrArguments) { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + params_start_position, + ))); + } + // It is a Syntax Error if any element of the BoundNames of FormalParameters // also occurs in the LexicallyDeclaredNames of FunctionBody. // https://tc39.es/ecma262/#sec-function-definitions-static-semantics-early-errors From 53e7366f7345ca747ea45c616056ebe07adec145 Mon Sep 17 00:00:00 2001 From: raskad <32105367+raskad@users.noreply.github.com> Date: Thu, 5 Jan 2023 03:47:25 +0100 Subject: [PATCH 2/2] Apply suggestions --- .../primary/async_function_expression/mod.rs | 23 ++++++++---------- .../primary/async_generator_expression/mod.rs | 23 ++++++++---------- .../primary/function_expression/mod.rs | 24 +++++++++---------- .../primary/generator_expression/mod.rs | 23 ++++++++---------- 4 files changed, 41 insertions(+), 52 deletions(-) diff --git a/boa_parser/src/parser/expression/primary/async_function_expression/mod.rs b/boa_parser/src/parser/expression/primary/async_function_expression/mod.rs index f443396e4dc..4c759a764ae 100644 --- a/boa_parser/src/parser/expression/primary/async_function_expression/mod.rs +++ b/boa_parser/src/parser/expression/primary/async_function_expression/mod.rs @@ -115,13 +115,15 @@ where // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - if (cursor.strict_mode() || body.strict()) - && [Some(Sym::EVAL), Some(Sym::ARGUMENTS)].contains(&name.map(Identifier::sym)) - { - return Err(Error::lex(LexError::Syntax( - "unexpected identifier 'eval' or 'arguments' in strict mode".into(), - name_span.start(), - ))); + if let Some(name) = name { + if (cursor.strict_mode() || body.strict()) + && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } } // Catch early error for BindingIdentifier, because strictness of the functions body is also @@ -142,12 +144,7 @@ where params_start_position, )?; - let function = AsyncFunction::new( - if name.is_some() { name } else { self.name }, - params, - body, - name.is_some(), - ); + let function = AsyncFunction::new(name.or(self.name), params, body, name.is_some()); if contains(&function, ContainsSymbol::Super) { return Err(Error::lex(LexError::Syntax( diff --git a/boa_parser/src/parser/expression/primary/async_generator_expression/mod.rs b/boa_parser/src/parser/expression/primary/async_generator_expression/mod.rs index e79b692ad25..bc76a065536 100644 --- a/boa_parser/src/parser/expression/primary/async_generator_expression/mod.rs +++ b/boa_parser/src/parser/expression/primary/async_generator_expression/mod.rs @@ -153,13 +153,15 @@ where // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - if (cursor.strict_mode() || body.strict()) - && [Some(Sym::EVAL), Some(Sym::ARGUMENTS)].contains(&name.map(Identifier::sym)) - { - return Err(Error::lex(LexError::Syntax( - "unexpected identifier 'eval' or 'arguments' in strict mode".into(), - name_span.start(), - ))); + if let Some(name) = name { + if (cursor.strict_mode() || body.strict()) + && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } } // Catch early error for BindingIdentifier, because strictness of the functions body is also @@ -179,12 +181,7 @@ where params_start_position, )?; - let function = AsyncGenerator::new( - if name.is_some() { name } else { self.name }, - params, - body, - name.is_some(), - ); + let function = AsyncGenerator::new(name.or(self.name), params, body, name.is_some()); if contains(&function, ContainsSymbol::Super) { return Err(Error::lex(LexError::Syntax( diff --git a/boa_parser/src/parser/expression/primary/function_expression/mod.rs b/boa_parser/src/parser/expression/primary/function_expression/mod.rs index d9d98150f7a..e7c05d6f791 100644 --- a/boa_parser/src/parser/expression/primary/function_expression/mod.rs +++ b/boa_parser/src/parser/expression/primary/function_expression/mod.rs @@ -110,13 +110,15 @@ where // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - if (cursor.strict_mode() || body.strict()) - && [Some(Sym::EVAL), Some(Sym::ARGUMENTS)].contains(&name.map(Identifier::sym)) - { - return Err(Error::lex(LexError::Syntax( - "unexpected identifier 'eval' or 'arguments' in strict mode".into(), - name_span.start(), - ))); + if let Some(name) = name { + if (cursor.strict_mode() || body.strict()) + && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } } // Catch early error for BindingIdentifier, because strictness of the functions body is also @@ -137,12 +139,8 @@ where params_start_position, )?; - let function = Function::new_with_binding_identifier( - if name.is_some() { name } else { self.name }, - params, - body, - name.is_some(), - ); + let function = + Function::new_with_binding_identifier(name.or(self.name), params, body, name.is_some()); if contains(&function, ContainsSymbol::Super) { return Err(Error::lex(LexError::Syntax( diff --git a/boa_parser/src/parser/expression/primary/generator_expression/mod.rs b/boa_parser/src/parser/expression/primary/generator_expression/mod.rs index a8683e03142..f482de57828 100644 --- a/boa_parser/src/parser/expression/primary/generator_expression/mod.rs +++ b/boa_parser/src/parser/expression/primary/generator_expression/mod.rs @@ -118,13 +118,15 @@ where // Early Error: If BindingIdentifier is present and the source code matching BindingIdentifier is strict mode code, // it is a Syntax Error if the StringValue of BindingIdentifier is "eval" or "arguments". - if (cursor.strict_mode() || body.strict()) - && [Some(Sym::EVAL), Some(Sym::ARGUMENTS)].contains(&name.map(Identifier::sym)) - { - return Err(Error::lex(LexError::Syntax( - "unexpected identifier 'eval' or 'arguments' in strict mode".into(), - name_span.start(), - ))); + if let Some(name) = name { + if (cursor.strict_mode() || body.strict()) + && [Sym::EVAL, Sym::ARGUMENTS].contains(&name.sym()) + { + return Err(Error::lex(LexError::Syntax( + "unexpected identifier 'eval' or 'arguments' in strict mode".into(), + name_span.start(), + ))); + } } // Catch early error for BindingIdentifier, because strictness of the functions body is also @@ -154,12 +156,7 @@ where ))); } - let function = Generator::new( - if name.is_some() { name } else { self.name }, - params, - body, - name.is_some(), - ); + let function = Generator::new(name.or(self.name), params, body, name.is_some()); if contains(&function, ContainsSymbol::Super) { return Err(Error::lex(LexError::Syntax(