Skip to content

Commit baa74e9

Browse files
committed
avm2: Enable stack traces for Flash Player 11.5+ and SWF18+
For Flash Player 11.5+ and SWF18+, stack traces are always enabled. Some content uses this behavior to verify whether the user is using Flash Player 11.5 onwards. For Flash Player 11.4 and earlier or SWF<18, stack traces are enabled only in the debug build. See <https://docs.ruffle.rs/en_US/FlashPlatform/reference/actionscript/3/Error.html#getStackTrace()>
1 parent 93b8f63 commit baa74e9

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

core/src/avm2/globals/error.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::avm2::string::AvmString;
44
use crate::avm2::value::Value;
55
use crate::avm2::Error;
66
use crate::avm2::TObject;
7+
use crate::PlayerMode;
78

89
pub fn call_handler<'gc>(
910
activation: &mut Activation<'_, 'gc>,
@@ -24,6 +25,22 @@ pub fn get_stack_trace<'gc>(
2425
) -> Result<Value<'gc>, Error<'gc>> {
2526
let this = this.as_object().unwrap();
2627

28+
// See <https://docs.ruffle.rs/en_US/FlashPlatform/reference/actionscript/3/Error.html#getStackTrace()>
29+
// But note that the behavior also depends on SWF version.
30+
let stack_trace_enabled = if activation.context.player_version >= 18
31+
&& activation.caller_movie_or_root().version() >= 18
32+
{
33+
// For Flash Player 11.5+ and SWF>=18, stack traces are always enabled.
34+
true
35+
} else {
36+
// For Flash Player Player 11.4 and earlier, or for SWF<18, stack traces are enabled for debug only.
37+
activation.context.player_mode == PlayerMode::Debug
38+
};
39+
40+
if !stack_trace_enabled {
41+
return Ok(Value::Null);
42+
}
43+
2744
if let Some(error) = this.as_error_object() {
2845
let call_stack = error.call_stack();
2946
if !call_stack.is_empty() {

core/src/avm2/object/error_object.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use crate::string::WString;
1010
use core::fmt;
1111
use gc_arena::{Collect, Gc, GcWeak};
1212
use std::fmt::Debug;
13-
use tracing::{enabled, Level};
1413

1514
/// A class instance allocator that allocates Error objects.
1615
pub fn error_allocator<'gc>(
@@ -19,9 +18,8 @@ pub fn error_allocator<'gc>(
1918
) -> Result<Object<'gc>, Error<'gc>> {
2019
let base = ScriptObjectData::new(class);
2120

22-
let call_stack = (enabled!(Level::INFO) || cfg!(feature = "avm_debug"))
23-
.then(|| activation.avm2().call_stack().borrow().clone())
24-
.unwrap_or_default();
21+
// Stack trace is always collected for debugging purposes.
22+
let call_stack = activation.avm2().call_stack().borrow().clone();
2523

2624
Ok(ErrorObject(Gc::new(
2725
activation.gc(),

0 commit comments

Comments
 (0)