Browse Source

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.
pull/2852/head
José Julián Espina 2 years ago
parent
commit
65f910523b
  1. 6
      boa_engine/src/environments/runtime.rs
  2. 6
      boa_engine/src/vm/opcode/define/mod.rs
  3. 7
      boa_engine/src/vm/opcode/set/name.rs

6
boa_engine/src/environments/runtime.rs

@ -951,6 +951,7 @@ impl Context<'_> {
mut binding_index: usize,
name: Identifier,
value: JsValue,
strict: bool,
) -> JsResult<bool> {
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<bool> {
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);
}
}
}

6
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())

7
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!(

Loading…
Cancel
Save