diff --git a/core/src/loader.rs b/core/src/loader.rs index 20a1712155b5..308adf2e43b5 100644 --- a/core/src/loader.rs +++ b/core/src/loader.rs @@ -254,6 +254,30 @@ impl<'gc> LoadManager<'gc> { self.0.get_mut(handle) } + /// Checks if the target clip on the given handle's loader + /// has been `avm1_removed()`. If so, it will set the `loader_status` + /// to `Failed` and return `true`. + /// This is used to prevent a loaded movie from executing + /// if its target clip was removed before it finished loading. + // TODO: Does this need adjusted for clip unloading? + // (see the avm1/load_cancel_via_unloadclip and avm1/load_cancel_via_unloadmovie tests) + pub fn load_cancelled_avm1(&mut self, handle: LoaderHandle) -> bool { + match self.get_loader_mut(handle) { + Some(MovieLoader { + loader_status, + target_clip, + .. + }) => { + if target_clip.avm1_removed() { + *loader_status = LoaderStatus::Failed; + return true; + } + } + _ => unreachable!(), + } + false + } + /// Kick off a movie clip load. /// /// Returns the loader's async process, which you will need to spawn. @@ -658,6 +682,11 @@ impl<'gc> MovieLoader<'gc> { None => return Err(Error::Cancelled), }; + if uc.load_manager.load_cancelled_avm1(handle) { + tracing::warn!("movie_loader: Target clip was already AVM1 removed"); + return Err(Error::Cancelled); + } + replacing_root_movie = uc .stage .root_clip() @@ -1590,6 +1619,11 @@ impl<'gc> MovieLoader<'gc> { None => return Err(Error::Cancelled), }; + if uc.load_manager.load_cancelled_avm1(handle) { + tracing::warn!("movie_loader_data: Target clip was already avm1_removed"); + return Ok(()); + } + let domain = if let MovieLoaderVMData::Avm2 { context, default_domain, diff --git a/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/child.swf b/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/child.swf new file mode 100644 index 000000000000..1ad3ba067623 Binary files /dev/null and b/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/child.swf differ diff --git a/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/output.txt b/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/output.txt new file mode 100644 index 000000000000..8cc4b5e45c7e --- /dev/null +++ b/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/output.txt @@ -0,0 +1,4 @@ +mc_loadMovie: _level0.mc_loadMovie +mc_loadMovie: +mc_mcl: _level0.mc_mcl +mc_mcl: diff --git a/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/test.swf b/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/test.swf new file mode 100644 index 000000000000..81749d91ddab Binary files /dev/null and b/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/test.swf differ diff --git a/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/test.toml b/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/test.toml new file mode 100644 index 000000000000..7cfc6eecb636 --- /dev/null +++ b/tests/tests/swfs/avm1/load_cancel_via_removemovieclip/test.toml @@ -0,0 +1 @@ +num_ticks = 4 diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadclip/child.swf b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/child.swf new file mode 100644 index 000000000000..1ad3ba067623 Binary files /dev/null and b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/child.swf differ diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadclip/output.ruffle.txt b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/output.ruffle.txt new file mode 100644 index 000000000000..b3be9444718f --- /dev/null +++ b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/output.ruffle.txt @@ -0,0 +1,5 @@ +mc_mcl: _level0.mc_mcl +mc_mcl: _level0.mc_mcl +MovieClipLoader.onLoadStart +_level0.mc_mcl - this should not trace! +MovieClipLoader.onLoadInit diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadclip/output.txt b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/output.txt new file mode 100644 index 000000000000..07c4cd24a28a --- /dev/null +++ b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/output.txt @@ -0,0 +1,3 @@ +mc_mcl: _level0.mc_mcl +mc_mcl: _level0.mc_mcl +MovieClipLoader.onLoadStart diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadclip/test.swf b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/test.swf new file mode 100644 index 000000000000..112a9548c250 Binary files /dev/null and b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/test.swf differ diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadclip/test.toml b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/test.toml new file mode 100644 index 000000000000..2fdc08c7a551 --- /dev/null +++ b/tests/tests/swfs/avm1/load_cancel_via_unloadclip/test.toml @@ -0,0 +1,2 @@ +num_ticks = 4 +known_failure = true diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/child.swf b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/child.swf new file mode 100644 index 000000000000..1ad3ba067623 Binary files /dev/null and b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/child.swf differ diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/output.ruffle.txt b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/output.ruffle.txt new file mode 100644 index 000000000000..ff647b01b85a --- /dev/null +++ b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/output.ruffle.txt @@ -0,0 +1,8 @@ +mc_loadMovie: _level0.mc_loadMovie +mc_loadMovie: _level0.mc_loadMovie +mc_mcl: _level0.mc_mcl +mc_mcl: _level0.mc_mcl +MovieClipLoader.onLoadStart +_level0.mc_mcl - this should not trace! +_level0.mc_loadMovie - this should not trace! +MovieClipLoader.onLoadInit diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/output.txt b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/output.txt new file mode 100644 index 000000000000..f54cbb004567 --- /dev/null +++ b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/output.txt @@ -0,0 +1,5 @@ +mc_loadMovie: _level0.mc_loadMovie +mc_loadMovie: _level0.mc_loadMovie +mc_mcl: _level0.mc_mcl +mc_mcl: _level0.mc_mcl +MovieClipLoader.onLoadStart diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/test.swf b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/test.swf new file mode 100644 index 000000000000..e23e2ff48a2d Binary files /dev/null and b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/test.swf differ diff --git a/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/test.toml b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/test.toml new file mode 100644 index 000000000000..2fdc08c7a551 --- /dev/null +++ b/tests/tests/swfs/avm1/load_cancel_via_unloadmovie/test.toml @@ -0,0 +1,2 @@ +num_ticks = 4 +known_failure = true