diff --git a/core/src/avm2/globals/error.rs b/core/src/avm2/globals/error.rs index a553ed99c104..3927648feb14 100644 --- a/core/src/avm2/globals/error.rs +++ b/core/src/avm2/globals/error.rs @@ -2,8 +2,8 @@ use crate::avm2::Error; use crate::avm2::activation::Activation; pub use crate::avm2::object::error_allocator; use crate::avm2::parameters::ParametersExt; -use crate::avm2::string::AvmString; use crate::avm2::value::Value; +use crate::string::{AvmString, WString}; use crate::{PlayerMode, avm2_stub_method}; pub fn get_error_message<'gc>( @@ -42,10 +42,13 @@ pub fn get_stack_trace<'gc>( } if let Some(error) = this.as_error_object() { - let call_stack = error.call_stack(); - if !call_stack.is_empty() { - return Ok(AvmString::new(activation.gc(), error.display_full()).into()); - } + let stringified = Value::from(error).coerce_to_string(activation)?; + + let mut output = WString::new(); + output.push_str(&stringified); + error.call_stack().display(&mut output); + + return Ok(AvmString::new(activation.gc(), output).into()); } Ok(Value::Null) } diff --git a/core/src/avm2/object/error_object.rs b/core/src/avm2/object/error_object.rs index 3f4c227aede5..21d5c7a240b0 100644 --- a/core/src/avm2/object/error_object.rs +++ b/core/src/avm2/object/error_object.rs @@ -112,13 +112,6 @@ impl<'gc> ErrorObject<'gc> { output } - pub fn display_full(self) -> WString { - let mut output = WString::new(); - output.push_str(&self.display()); - self.call_stack().display(&mut output); - output - } - pub fn call_stack(&self) -> &CallStack<'gc> { &self.0.call_stack } diff --git a/tests/tests/swfs/avm2/error_stack_trace_edge_cases/Test.as b/tests/tests/swfs/avm2/error_stack_trace_edge_cases/Test.as new file mode 100644 index 000000000000..d3465bb12bd1 --- /dev/null +++ b/tests/tests/swfs/avm2/error_stack_trace_edge_cases/Test.as @@ -0,0 +1,21 @@ +package { + import flash.display.MovieClip; + + public class Test extends MovieClip { + public function Test() { + var err:Error = new Error(); + + Error.prototype.toString = function():String { + trace("toString called (1)"); + return "from toString"; + }; + trace(err.getStackTrace()); + + Error.prototype.toString = function():String { + trace("toString called (2)"); + return null; + }; + trace(err.getStackTrace()); + } + } +} diff --git a/tests/tests/swfs/avm2/error_stack_trace_edge_cases/output.txt b/tests/tests/swfs/avm2/error_stack_trace_edge_cases/output.txt new file mode 100644 index 000000000000..5c99e48f91b2 --- /dev/null +++ b/tests/tests/swfs/avm2/error_stack_trace_edge_cases/output.txt @@ -0,0 +1,6 @@ +toString called (1) +from toString + at Test() +toString called (2) +null + at Test() diff --git a/tests/tests/swfs/avm2/error_stack_trace_edge_cases/test.swf b/tests/tests/swfs/avm2/error_stack_trace_edge_cases/test.swf new file mode 100644 index 000000000000..20c95cf2bc19 Binary files /dev/null and b/tests/tests/swfs/avm2/error_stack_trace_edge_cases/test.swf differ diff --git a/tests/tests/swfs/avm2/error_stack_trace_edge_cases/test.toml b/tests/tests/swfs/avm2/error_stack_trace_edge_cases/test.toml new file mode 100644 index 000000000000..dbee897f5863 --- /dev/null +++ b/tests/tests/swfs/avm2/error_stack_trace_edge_cases/test.toml @@ -0,0 +1 @@ +num_frames = 1