From a3727e0727723c82f5955e052460ebad2cbcc742 Mon Sep 17 00:00:00 2001 From: relrelb Date: Wed, 31 Mar 2021 00:37:52 +0300 Subject: [PATCH] avm1: Fix "this" argument conversion in Function.prototype.{call,apply} The "this" argument should fall-back to the global object only for undefined or null. Other primitives should be coerced to an object rather than falling-back to the global object. As a drive-by replace `Vec::new` by `Vec::with_capacity` in `Function.prototype.apply` to minimize unnecessary reallocations. --- core/src/avm1/globals/function.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/avm1/globals/function.rs b/core/src/avm1/globals/function.rs index 2d5f6efdc..f03b69f02 100644 --- a/core/src/avm1/globals/function.rs +++ b/core/src/avm1/globals/function.rs @@ -37,8 +37,8 @@ pub fn call<'gc>( myargs: &[Value<'gc>], ) -> Result, Error<'gc>> { let this = match myargs.get(0) { - Some(Value::Object(this)) => *this, - _ => activation.context.avm1.globals, + Some(Value::Undefined) | Some(Value::Null) | None => activation.context.avm1.globals, + Some(this_val) => this_val.coerce_to_object(activation), }; let empty = []; let args = match myargs.len() { @@ -68,16 +68,16 @@ pub fn apply<'gc>( myargs: &[Value<'gc>], ) -> Result, Error<'gc>> { let this = match myargs.get(0) { - Some(Value::Object(this)) => *this, - _ => activation.context.avm1.globals, + Some(Value::Undefined) | Some(Value::Null) | None => activation.context.avm1.globals, + Some(this_val) => this_val.coerce_to_object(activation), }; - let mut child_args = Vec::new(); let args_object = myargs.get(1).cloned().unwrap_or(Value::Undefined); let length = match args_object { Value::Object(a) => a.get("length", activation)?.coerce_to_f64(activation)? as usize, _ => 0, }; + let mut child_args = Vec::with_capacity(length); while child_args.len() < length { let args = args_object.coerce_to_object(activation); let next_arg = args.get(&format!("{}", child_args.len()), activation)?;