From d70f6ace24a96359b223b8d0415fdd4ddda70939 Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Fri, 20 Jun 2025 09:07:28 +0200 Subject: [PATCH] Add top-level creation URL for global scope (#37342) Global scopes have two creation URLs: one for itself and one for the "top-level" scope. It's not immediately obvious what is considered top-level here (it is not strictly defined in the specification). In any case, reports need the creation URL of the scope itself, not the top-level version. Therefore, propagate this information from all scopes, where the worker and worklets remain to pass in `None` for their top-level scope. Part of #37328 --------- Signed-off-by: Tim van der Lippe --- .../script/dom/dissimilaroriginwindow.rs | 1 + components/script/dom/globalscope.rs | 46 +++++++++++++++---- components/script/dom/window.rs | 6 ++- components/script/dom/workerglobalscope.rs | 1 + components/script/dom/workletglobalscope.rs | 1 + components/script/script_thread.rs | 5 ++ .../constellation/from_script_message.rs | 2 +- 7 files changed, 50 insertions(+), 12 deletions(-) diff --git a/components/script/dom/dissimilaroriginwindow.rs b/components/script/dom/dissimilaroriginwindow.rs index 70c384db822..96554b605b6 100644 --- a/components/script/dom/dissimilaroriginwindow.rs +++ b/components/script/dom/dissimilaroriginwindow.rs @@ -61,6 +61,7 @@ impl DissimilarOriginWindow { global_to_clone_from.resource_threads().clone(), global_to_clone_from.origin().clone(), global_to_clone_from.creation_url().clone(), + global_to_clone_from.top_level_creation_url().clone(), // FIXME(nox): The microtask queue is probably not important // here, but this whole DOM interface is a hack anyway. global_to_clone_from.microtask_queue().clone(), diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 597dd5875cd..492cccb66c1 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -283,7 +283,11 @@ pub(crate) struct GlobalScope { /// #[no_trace] - creation_url: Option, + creation_url: ServoUrl, + + /// + #[no_trace] + top_level_creation_url: Option, /// A map for storing the previous permission state read results. permission_state_invocation_results: DomRefCell>, @@ -740,7 +744,8 @@ impl GlobalScope { script_to_constellation_chan: ScriptToConstellationChan, resource_threads: ResourceThreads, origin: MutableOrigin, - creation_url: Option, + creation_url: ServoUrl, + top_level_creation_url: Option, microtask_queue: Rc, #[cfg(feature = "webgpu")] gpu_id_hub: Arc, inherited_secure_context: Option, @@ -769,6 +774,7 @@ impl GlobalScope { timers: OnceCell::default(), origin, creation_url, + top_level_creation_url, permission_state_invocation_results: Default::default(), microtask_queue, list_auto_close_worker: Default::default(), @@ -2474,10 +2480,15 @@ impl GlobalScope { } /// Get the creation_url for this global scope - pub(crate) fn creation_url(&self) -> &Option { + pub(crate) fn creation_url(&self) -> &ServoUrl { &self.creation_url } + /// Get the top_level_creation_url for this global scope + pub(crate) fn top_level_creation_url(&self) -> &Option { + &self.top_level_creation_url + } + pub(crate) fn image_cache(&self) -> Arc { if let Some(window) = self.downcast::() { return window.image_cache(); @@ -3525,13 +3536,30 @@ impl GlobalScope { if Some(false) == self.inherited_secure_context { return false; } - if let Some(creation_url) = self.creation_url() { - if creation_url.scheme() == "blob" && Some(true) == self.inherited_secure_context { - return true; - } - return creation_url.is_potentially_trustworthy(); + // Step 1. If environment is an environment settings object, then: + // Step 1.1. Let global be environment's global object. + match self.top_level_creation_url() { + None => { + // Workers and worklets don't have a top-level creation URL + assert!( + self.downcast::().is_some() || + self.downcast::().is_some() + ); + true + }, + Some(top_level_creation_url) => { + assert!(self.downcast::().is_some()); + // Step 2. If the result of Is url potentially trustworthy? + // given environment's top-level creation URL is "Potentially Trustworthy", then return true. + // Step 3. Return false. + if top_level_creation_url.scheme() == "blob" && + Some(true) == self.inherited_secure_context + { + return true; + } + top_level_creation_url.is_potentially_trustworthy() + }, } - false } /// diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index f653cf580f9..cc19982cd10 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -3052,7 +3052,8 @@ impl Window { parent_info: Option, viewport_details: ViewportDetails, origin: MutableOrigin, - creator_url: ServoUrl, + creation_url: ServoUrl, + top_level_creation_url: ServoUrl, navigation_start: CrossProcessInstant, webgl_chan: Option, #[cfg(feature = "webxr")] webxr_registry: Option, @@ -3088,7 +3089,8 @@ impl Window { constellation_chan, resource_threads, origin, - Some(creator_url), + creation_url, + Some(top_level_creation_url), microtask_queue, #[cfg(feature = "webgpu")] gpu_id_hub, diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index aae1ba9f595..061e6a2777b 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -171,6 +171,7 @@ impl WorkerGlobalScope { init.resource_threads, MutableOrigin::new(init.origin), init.creation_url, + None, runtime.microtask_queue.clone(), #[cfg(feature = "webgpu")] gpu_id_hub, diff --git a/components/script/dom/workletglobalscope.rs b/components/script/dom/workletglobalscope.rs index c478830ac0c..c20fd59c1c7 100644 --- a/components/script/dom/workletglobalscope.rs +++ b/components/script/dom/workletglobalscope.rs @@ -104,6 +104,7 @@ impl WorkletGlobalScope { script_to_constellation_chan, init.resource_threads.clone(), MutableOrigin::new(ImmutableOrigin::new_opaque()), + base_url.clone(), None, Default::default(), #[cfg(feature = "webgpu")] diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index f49e24ad5ed..4012ee9aaf7 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -3395,6 +3395,11 @@ impl ScriptThread { incomplete.viewport_details, origin.clone(), final_url.clone(), + // TODO(37417): Set correct top-level URL here. Currently, we only specify the + // url of the current window. However, in case this is an iframe, we should + // pass in the URL from the frame that includes the iframe (which potentially + // is another nested iframe in a frame). + final_url.clone(), incomplete.navigation_start, self.webgl_chan.as_ref().map(|chan| chan.channel()), #[cfg(feature = "webxr")] diff --git a/components/shared/constellation/from_script_message.rs b/components/shared/constellation/from_script_message.rs index b0fbcd097d4..b860aa25dd4 100644 --- a/components/shared/constellation/from_script_message.rs +++ b/components/shared/constellation/from_script_message.rs @@ -443,7 +443,7 @@ pub struct WorkerGlobalScopeInit { /// The origin pub origin: ImmutableOrigin, /// The creation URL - pub creation_url: Option, + pub creation_url: ServoUrl, /// True if secure context pub inherited_secure_context: Option, }