From 0367f6a8d4572660682d609ec4a94cf31439d1c9 Mon Sep 17 00:00:00 2001 From: relrelb Date: Sat, 17 Jul 2021 21:16:32 +0300 Subject: [PATCH] avm1: Correct `ASSetPropFlags` * The properties parameter is evaluated last. This is observable by the order the `toString`/`valueOf` methods of the parameters are called. * Only `null` in the property list parameter configures all properties, as opposed to `undefined`, `null`, numbers and booleans previously. * Objects in the property list parameter are not handled specially. Instead, they're also coerced to string and split by comma. --- core/src/avm1/globals/object.rs | 55 ++++++++++----------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/core/src/avm1/globals/object.rs b/core/src/avm1/globals/object.rs index 1cdfcc364..f22a202f6 100644 --- a/core/src/avm1/globals/object.rs +++ b/core/src/avm1/globals/object.rs @@ -263,8 +263,8 @@ pub fn as_set_prop_flags<'gc>( _: Object<'gc>, args: &[Value<'gc>], ) -> Result, Error<'gc>> { - let object = if let Some(object) = args.get(0).map(|v| v.coerce_to_object(activation)) { - object + let object = if let Some(v) = args.get(0) { + v.coerce_to_object(activation) } else { avm_warn!( activation, @@ -273,30 +273,6 @@ pub fn as_set_prop_flags<'gc>( return Ok(Value::Undefined); }; - let properties = match args.get(1) { - Some(Value::Object(ob)) => { - //Convert to native array. - //TODO: Can we make this an iterator? - let mut array = vec![]; - let length = ob.get("length", activation)?.coerce_to_f64(activation)? as usize; - for i in 0..length { - array.push( - ob.get(&format!("{}", i), activation)? - .coerce_to_string(activation)? - .to_string(), - ) - } - - Some(array) - } - Some(Value::String(s)) => Some(s.split(',').map(String::from).collect()), - Some(_) => None, - None => { - avm_warn!(activation, "ASSetPropFlags called without object list!"); - return Ok(Value::Undefined); - } - }; - let set_flags = args.get(2).unwrap_or(&0.into()).coerce_to_f64(activation)? as u8; let set_attributes = Attribute::from_bits_truncate(set_flags); @@ -310,23 +286,26 @@ pub fn as_set_prop_flags<'gc>( ); } - match properties { - Some(properties) => { - for prop_name in properties { - object.set_attributes( - activation.context.gc_context, - Some(&prop_name), - set_attributes, - clear_attributes, - ) - } - } - None => object.set_attributes( + match args.get(1) { + Some(&Value::Null) => object.set_attributes( activation.context.gc_context, None, set_attributes, clear_attributes, ), + Some(v) => { + for prop_name in v.coerce_to_string(activation)?.split(',') { + object.set_attributes( + activation.context.gc_context, + Some(prop_name), + set_attributes, + clear_attributes, + ) + } + } + None => { + avm_warn!(activation, "ASSetPropFlags called without property list!"); + } } Ok(Value::Undefined)