LibJS: Reject arguments/eval in strict mode destructuring and arrows
Check identifier name validity for destructuring assignment pattern bound names, and validate arrow function parameters after the arrow is confirmed rather than during speculative parameter parsing. This fixes arguments/eval as destructuring assignment targets and as arrow function parameter names in strict mode.
This commit is contained in:
parent
66dbb355fe
commit
49cc44a3eb
3 changed files with 26 additions and 7 deletions
|
|
@ -1307,7 +1307,12 @@ impl Parser<'_> {
|
|||
}
|
||||
let token = self.consume();
|
||||
let value = Utf16String::from(self.token_value(&token));
|
||||
self.check_identifier_name_for_assignment_validity(&value, false);
|
||||
// Skip validity check for arrow functions; arrow parameter
|
||||
// parsing is speculative and errors would abort the parse.
|
||||
// The check runs after the arrow is confirmed instead.
|
||||
if !is_arrow {
|
||||
self.check_identifier_name_for_assignment_validity(&value, false);
|
||||
}
|
||||
let id = Rc::new(Identifier::new(
|
||||
self.range_from(formal_parameters_start),
|
||||
value.clone(),
|
||||
|
|
|
|||
|
|
@ -856,8 +856,11 @@ impl Parser<'_> {
|
|||
|
||||
// Register synthesized identifiers with the scope collector so
|
||||
// they get resolved as locals during analyze().
|
||||
for (name, id) in self.pattern_bound_names.drain(..) {
|
||||
self.scope_collector.register_identifier(id, &name, None);
|
||||
let bound_names: Vec<_> = self.pattern_bound_names.drain(..).collect();
|
||||
for (name, id) in &bound_names {
|
||||
self.check_identifier_name_for_assignment_validity(name, false);
|
||||
self.scope_collector
|
||||
.register_identifier(id.clone(), name, None);
|
||||
}
|
||||
self.pattern_bound_names = saved_bound_names;
|
||||
self.consume();
|
||||
|
|
@ -2457,8 +2460,12 @@ impl Parser<'_> {
|
|||
self.scope_collector.close_scope();
|
||||
self.pattern_bound_names = saved_pattern_bound_names;
|
||||
|
||||
if has_use_strict || fn_kind != FunctionKind::Normal {
|
||||
self.check_parameters_post_body(¶meter_info, has_use_strict, fn_kind);
|
||||
if has_use_strict || fn_kind != FunctionKind::Normal || self.flags.strict_mode {
|
||||
self.check_parameters_post_body(
|
||||
¶meter_info,
|
||||
has_use_strict || self.flags.strict_mode,
|
||||
fn_kind,
|
||||
);
|
||||
}
|
||||
|
||||
self.flags.await_expression_is_valid = saved_await_body;
|
||||
|
|
@ -2505,6 +2512,10 @@ impl Parser<'_> {
|
|||
self.scope_collector.close_scope();
|
||||
self.pattern_bound_names = saved_pattern_bound_names;
|
||||
|
||||
if self.flags.strict_mode || fn_kind != FunctionKind::Normal {
|
||||
self.check_parameters_post_body(¶meter_info, self.flags.strict_mode, fn_kind);
|
||||
}
|
||||
|
||||
self.flags.await_expression_is_valid = saved_await_body;
|
||||
self.flags.in_class_static_init_block = saved_static_init;
|
||||
self.flags.in_formal_parameter_context = saved_formal_parameter_ctx;
|
||||
|
|
|
|||
|
|
@ -979,8 +979,11 @@ impl Parser<'_> {
|
|||
{
|
||||
let pattern = self.synthesize_binding_pattern(init_start);
|
||||
|
||||
for (name, id) in self.pattern_bound_names.drain(..) {
|
||||
self.scope_collector.register_identifier(id, &name, None);
|
||||
let bound_names: Vec<_> = self.pattern_bound_names.drain(..).collect();
|
||||
for (name, id) in &bound_names {
|
||||
self.check_identifier_name_for_assignment_validity(name, false);
|
||||
self.scope_collector
|
||||
.register_identifier(id.clone(), name, None);
|
||||
}
|
||||
ForInOfLhs::Pattern(pattern)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue