From 6998dafdb9c8c443b544f835f101af0c530cecc6 Mon Sep 17 00:00:00 2001 From: David Wendt Date: Tue, 21 Jul 2020 23:57:43 -0400 Subject: [PATCH] Store an origin URL on every movie that is loaded. --- core/src/avm1/activation.rs | 2 ++ core/src/avm1/globals/movie_clip.rs | 1 + core/src/avm1/globals/movie_clip_loader.rs | 1 + core/src/display_object/button.rs | 3 ++- core/src/display_object/movie_clip.rs | 2 +- core/src/loader.rs | 7 ++++-- core/src/tag_utils.rs | 26 +++++++++++++++------- web/src/lib.rs | 2 +- 8 files changed, 31 insertions(+), 13 deletions(-) diff --git a/core/src/avm1/activation.rs b/core/src/avm1/activation.rs index 402f451a0..a0c1ba396 100644 --- a/core/src/avm1/activation.rs +++ b/core/src/avm1/activation.rs @@ -1246,6 +1246,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> { context.player.clone().unwrap(), level, fetch, + url, None, ); context.navigator.spawn_future(process); @@ -1336,6 +1337,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> { context.player.clone().unwrap(), clip_target, fetch, + url.to_string(), None, ); context.navigator.spawn_future(process); diff --git a/core/src/avm1/globals/movie_clip.rs b/core/src/avm1/globals/movie_clip.rs index 05f276f22..a4bd722cc 100644 --- a/core/src/avm1/globals/movie_clip.rs +++ b/core/src/avm1/globals/movie_clip.rs @@ -1096,6 +1096,7 @@ fn load_movie<'gc>( context.player.clone().unwrap(), DisplayObject::MovieClip(target), fetch, + url.to_string(), None, ); diff --git a/core/src/avm1/globals/movie_clip_loader.rs b/core/src/avm1/globals/movie_clip_loader.rs index d52b63d0b..e5db9557d 100644 --- a/core/src/avm1/globals/movie_clip_loader.rs +++ b/core/src/avm1/globals/movie_clip_loader.rs @@ -135,6 +135,7 @@ pub fn load_clip<'gc>( context.player.clone().unwrap(), DisplayObject::MovieClip(movieclip), fetch, + url.to_string(), Some(this), ); diff --git a/core/src/display_object/button.rs b/core/src/display_object/button.rs index 4199705f6..ad6bda6b0 100644 --- a/core/src/display_object/button.rs +++ b/core/src/display_object/button.rs @@ -34,7 +34,8 @@ impl<'gc> Button<'gc> { ) -> Self { let mut actions = vec![]; for action in &button.actions { - let action_data = source_movie.owned_subslice(action.action_data.clone()); + let action_data = + source_movie.owned_subslice(action.action_data.clone(), &source_movie.movie); for condition in &action.conditions { let button_action = ButtonAction { action_data: action_data.clone(), diff --git a/core/src/display_object/movie_clip.rs b/core/src/display_object/movie_clip.rs index c95e76b53..4c7d316e8 100644 --- a/core/src/display_object/movie_clip.rs +++ b/core/src/display_object/movie_clip.rs @@ -2567,7 +2567,7 @@ impl ClipAction { let len = other.action_data.len(); let key_code = other.key_code; - let movie = Arc::new(movie.from_movie_and_subdata(other.action_data)); + let movie = Arc::new(movie.from_movie_and_subdata(other.action_data, &movie)); other.events.into_iter().map(move |event| Self { event: match event { ClipEventFlag::Construct => ClipEvent::Construct, diff --git a/core/src/loader.rs b/core/src/loader.rs index 1384d40ce..f15d4ae3f 100644 --- a/core/src/loader.rs +++ b/core/src/loader.rs @@ -116,6 +116,7 @@ impl<'gc> LoadManager<'gc> { player: Weak>, target_clip: DisplayObject<'gc>, fetch: OwnedFuture, Error>, + url: String, target_broadcaster: Option>, ) -> OwnedFuture<(), Error> { let loader = Loader::Movie { @@ -129,7 +130,7 @@ impl<'gc> LoadManager<'gc> { let loader = self.get_loader_mut(handle).unwrap(); loader.introduce_loader_handle(handle); - loader.movie_loader(player, fetch) + loader.movie_loader(player, fetch, url) } /// Indicates that a movie clip has initialized (ran it's first frame). @@ -331,6 +332,7 @@ impl<'gc> Loader<'gc> { &mut self, player: Weak>, fetch: OwnedFuture, Error>, + url: String, ) -> OwnedFuture<(), Error> { let handle = match self { Loader::Movie { self_handle, .. } => self_handle.expect("Loader not self-introduced"), @@ -375,7 +377,8 @@ impl<'gc> Loader<'gc> { }, )?; - let data = (fetch.await).and_then(|data| Ok((data.len(), SwfMovie::from_data(&data)?))); + let data = (fetch.await) + .and_then(|data| Ok((data.len(), SwfMovie::from_data(&data, Some(url))?))); if let Ok((length, movie)) = data { let movie = Arc::new(movie); diff --git a/core/src/tag_utils.rs b/core/src/tag_utils.rs index e4f503c71..e6fdbc834 100644 --- a/core/src/tag_utils.rs +++ b/core/src/tag_utils.rs @@ -17,6 +17,9 @@ pub struct SwfMovie { /// Uncompressed SWF data. data: Vec, + + /// The URL the SWF was downloaded from. + url: Option, } impl SwfMovie { @@ -31,25 +34,32 @@ impl SwfMovie { num_frames: 0, }, data: vec![], + url: None, } } - /// Construct a movie from an existing movie with any particular data on it. - pub fn from_movie_and_subdata(&self, data: Vec) -> Self { + /// Construct a movie from an existing movie with any particular data on + /// it. + /// + /// Use of this method is discouraged. SWF data should be borrowed or + /// sliced as necessary to refer to partial sections of a file. + pub fn from_movie_and_subdata(&self, data: Vec, source: &SwfMovie) -> Self { Self { header: self.header.clone(), data, + url: source.url.clone(), } } /// Utility method to construct a movie from a file on disk. pub fn from_path>(path: P) -> Result { + let url = path.as_ref().to_string_lossy().to_owned().to_string(); let data = std::fs::read(path)?; - Self::from_data(&data) + Self::from_data(&data, Some(url)) } /// Construct a movie based on the contents of the SWF datastream. - pub fn from_data(swf_data: &[u8]) -> Result { + pub fn from_data(swf_data: &[u8], url: Option) -> Result { let swf_stream = swf::read::read_swf_header(&swf_data[..])?; let header = swf_stream.header; let mut reader = swf_stream.reader; @@ -74,7 +84,7 @@ impl SwfMovie { data }; - Ok(Self { header, data }) + Ok(Self { header, data, url }) } pub fn header(&self) -> &Header { @@ -141,12 +151,12 @@ impl SwfSlice { /// Construct a new slice with a given dataset only. /// /// This is used primarily for converting owned data back into a slice: we - /// reattach the SWF data that we can - pub fn owned_subslice(&self, data: Vec) -> Self { + /// reattach the SWF data to a fresh movie and return a new slice into it. + pub fn owned_subslice(&self, data: Vec, source: &SwfMovie) -> Self { let len = data.len(); Self { - movie: Arc::new(self.movie.from_movie_and_subdata(data)), + movie: Arc::new(self.movie.from_movie_and_subdata(data, source)), start: 0, end: len, } diff --git a/web/src/lib.rs b/web/src/lib.rs index 7398d3eb3..31483e910 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -113,7 +113,7 @@ impl Ruffle { let movie = { let mut data = vec![0; swf_data.length() as usize]; swf_data.copy_to(&mut data[..]); - SwfMovie::from_data(&data)? + SwfMovie::from_data(&data, None)? }; let window = web_sys::window().ok_or_else(|| "Expected window")?;