From 940529ac8a427e2423253b386b2a8d3861775ea8 Mon Sep 17 00:00:00 2001 From: raskad <32105367+raskad@users.noreply.github.com> Date: Sun, 4 Jun 2023 13:01:11 +0200 Subject: [PATCH] Fix panic in optional expressions with private identifiers (#2995) --- boa_ast/src/operations.rs | 26 ++++++++++++++++++- .../left_hand_side/optional/tests.rs | 8 ++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/boa_ast/src/operations.rs b/boa_ast/src/operations.rs index 02a43f29f3..2504bc0aef 100644 --- a/boa_ast/src/operations.rs +++ b/boa_ast/src/operations.rs @@ -15,7 +15,7 @@ use crate::{ expression::{ access::{PrivatePropertyAccess, SuperPropertyAccess}, operator::BinaryInPrivate, - Await, Identifier, SuperCall, Yield, + Await, Identifier, OptionalOperationKind, SuperCall, Yield, }, function::{ ArrowFunction, AsyncArrowFunction, AsyncFunction, AsyncGenerator, Class, ClassElement, @@ -976,6 +976,30 @@ impl<'ast> Visitor<'ast> for AllPrivateIdentifiersValidVisitor { ControlFlow::Break(()) } } + + fn visit_optional_operation_kind( + &mut self, + node: &'ast OptionalOperationKind, + ) -> ControlFlow { + match node { + OptionalOperationKind::SimplePropertyAccess { field } => { + self.visit_property_access_field(field) + } + OptionalOperationKind::PrivatePropertyAccess { field } => { + if self.0.contains(&field.description()) { + ControlFlow::Continue(()) + } else { + ControlFlow::Break(()) + } + } + OptionalOperationKind::Call { args } => { + for arg in args.iter() { + try_break!(self.visit_expression(arg)); + } + ControlFlow::Continue(()) + } + } + } } /// Errors that can occur when checking labels. diff --git a/boa_parser/src/parser/expression/left_hand_side/optional/tests.rs b/boa_parser/src/parser/expression/left_hand_side/optional/tests.rs index cce4ce68e6..cf640e49a8 100644 --- a/boa_parser/src/parser/expression/left_hand_side/optional/tests.rs +++ b/boa_parser/src/parser/expression/left_hand_side/optional/tests.rs @@ -89,3 +89,11 @@ const a = console?.log `Hello`"#, ); } + +#[test] +fn private_identifier_early_error() { + check_invalid_script("this?.#a"); + check_invalid_script("this.#a"); + check_invalid_script("this?.a?.#a"); + check_invalid_script("this.a.#a"); +}