From 65f910523b93df378ccf7f490779393c62d9e080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Juli=C3=A1n=20Espina?= Date: Thu, 20 Apr 2023 05:18:33 +0000 Subject: [PATCH] Fix setting properties inside `with` blocks (#2847) This preserves the semantics of the abstract operation `Set` on `with` blocks; setting non-writable properties on non-strict mode just silently fails. --- boa_engine/src/environments/runtime.rs | 6 ++++-- boa_engine/src/vm/opcode/define/mod.rs | 6 +++++- boa_engine/src/vm/opcode/set/name.rs | 7 ++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/boa_engine/src/environments/runtime.rs b/boa_engine/src/environments/runtime.rs index ddf9ae7946..ecc536d9a7 100644 --- a/boa_engine/src/environments/runtime.rs +++ b/boa_engine/src/environments/runtime.rs @@ -951,6 +951,7 @@ impl Context<'_> { mut binding_index: usize, name: Identifier, value: JsValue, + strict: bool, ) -> JsResult { for env_index in (environment_index + 1..self.vm.environments.stack.len()).rev() { let env = self.environment_expect(env_index); @@ -983,7 +984,7 @@ impl Context<'_> { continue; } } - return o.set(key, value, true, self); + return o.set(key, value, strict, self); } } } @@ -1017,6 +1018,7 @@ impl Context<'_> { &mut self, name: Identifier, value: &JsValue, + strict: bool, ) -> JsResult { for env_index in (0..self.vm.environments.stack.len()).rev() { let env = self.environment_expect(env_index); @@ -1056,7 +1058,7 @@ impl Context<'_> { continue; } } - return o.set(key, value.clone(), true, self); + return o.set(key, value.clone(), strict, self); } } } diff --git a/boa_engine/src/vm/opcode/define/mod.rs b/boa_engine/src/vm/opcode/define/mod.rs index 42aaa3bc68..9f04f782cd 100644 --- a/boa_engine/src/vm/opcode/define/mod.rs +++ b/boa_engine/src/vm/opcode/define/mod.rs @@ -59,7 +59,11 @@ impl Operation for DefInitVar { binding_locator.throw_mutate_immutable(context)?; if binding_locator.is_global() { - if !context.put_value_if_global_poisoned(binding_locator.name(), &value)? { + if !context.put_value_if_global_poisoned( + binding_locator.name(), + &value, + context.vm.frame().code_block.strict, + )? { let key = context .interner() .resolve_expect(binding_locator.name().sym()) diff --git a/boa_engine/src/vm/opcode/set/name.rs b/boa_engine/src/vm/opcode/set/name.rs index 65a99f7319..f764e82ff5 100644 --- a/boa_engine/src/vm/opcode/set/name.rs +++ b/boa_engine/src/vm/opcode/set/name.rs @@ -25,7 +25,11 @@ impl Operation for SetName { binding_locator.throw_mutate_immutable(context)?; if binding_locator.is_global() { - if !context.put_value_if_global_poisoned(binding_locator.name(), &value)? { + if !context.put_value_if_global_poisoned( + binding_locator.name(), + &value, + context.vm.frame().code_block.strict, + )? { let key: JsString = context .interner() .resolve_expect(binding_locator.name().sym()) @@ -55,6 +59,7 @@ impl Operation for SetName { binding_locator.binding_index(), binding_locator.name(), value, + context.vm.frame().code_block.strict, )? { return Err(JsNativeError::reference() .with_message(format!(