diff options
Diffstat (limited to 'components/script/dom/htmliframeelement.rs')
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 71 |
1 files changed, 38 insertions, 33 deletions
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index a85b9bfa915..58ddd48c8c9 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -37,8 +37,8 @@ use profile_traits::ipc as ProfiledIpc; use script_layout_interface::message::ReflowGoal; use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use script_traits::{ - IFrameLoadInfo, IFrameLoadInfoWithData, JsEvalResult, LoadData, UpdatePipelineIdReason, - WindowSizeData, + HistoryEntryReplacement, IFrameLoadInfo, IFrameLoadInfoWithData, JsEvalResult, LoadData, + LoadOrigin, UpdatePipelineIdReason, WindowSizeData, }; use script_traits::{NewLayoutInfo, ScriptMsg}; use servo_url::ServoUrl; @@ -109,9 +109,9 @@ impl HTMLIFrameElement { pub fn navigate_or_reload_child_browsing_context( &self, - mut load_data: Option<LoadData>, + mut load_data: LoadData, nav_type: NavigationType, - replace: bool, + replace: HistoryEntryReplacement, ) { let sandboxed = if self.is_sandboxed() { IFrameSandboxed @@ -136,30 +136,27 @@ impl HTMLIFrameElement { // document; the new navigation will continue blocking it. LoadBlocker::terminate(&mut load_blocker); - if let Some(ref mut load_data) = load_data { - let is_javascript = load_data.url.scheme() == "javascript"; - if is_javascript { - let window_proxy = self.GetContentWindow(); - if let Some(window_proxy) = window_proxy { - ScriptThread::eval_js_url(&window_proxy.global(), load_data); + if load_data.url.scheme() == "javascript" { + let window_proxy = self.GetContentWindow(); + if let Some(window_proxy) = window_proxy { + // Important re security. See https://github.com/servo/servo/issues/23373 + // TODO: check according to https://w3c.github.io/webappsec-csp/#should-block-navigation-request + if ScriptThread::check_load_origin(&load_data.load_origin, &document.url().origin()) + { + ScriptThread::eval_js_url(&window_proxy.global(), &mut load_data); } } } - //TODO(#9592): Deal with the case where an iframe is being reloaded so url is None. - // The iframe should always have access to the nested context's active - // document URL through the browsing context. - if let Some(ref load_data) = load_data { - match load_data.js_eval_result { - Some(JsEvalResult::NoContent) => (), - _ => { - *load_blocker = Some(LoadBlocker::new( - &*document, - LoadType::Subframe(load_data.url.clone()), - )); - }, - }; - } + match load_data.js_eval_result { + Some(JsEvalResult::NoContent) => (), + _ => { + *load_blocker = Some(LoadBlocker::new( + &*document, + LoadType::Subframe(load_data.url.clone()), + )); + }, + }; let window = window_from_node(self); let old_pipeline_id = self.pipeline_id(); @@ -182,6 +179,12 @@ impl HTMLIFrameElement { self.about_blank_pipeline_id.set(Some(new_pipeline_id)); + let load_info = IFrameLoadInfoWithData { + info: load_info, + load_data: load_data.clone(), + old_pipeline_id: old_pipeline_id, + sandbox: sandboxed, + }; global_scope .script_to_constellation_chan() .send(ScriptMsg::ScriptNewIFrame(load_info, pipeline_sender)) @@ -193,7 +196,7 @@ impl HTMLIFrameElement { browsing_context_id: browsing_context_id, top_level_browsing_context_id: top_level_browsing_context_id, opener: None, - load_data: load_data.unwrap(), + load_data: load_data, pipeline_port: pipeline_receiver, content_process_shutdown_chan: None, window_size: WindowSizeData { @@ -270,6 +273,7 @@ impl HTMLIFrameElement { let document = document_from_node(self); let load_data = LoadData::new( + LoadOrigin::Script(document.origin().immutable().clone()), url, creator_pipeline_id, Some(Referrer::ReferrerUrl(document.url())), @@ -281,12 +285,12 @@ impl HTMLIFrameElement { // see https://html.spec.whatwg.org/multipage/#the-iframe-element:about:blank-3 let is_about_blank = pipeline_id.is_some() && pipeline_id == self.about_blank_pipeline_id.get(); - let replace = is_about_blank; - self.navigate_or_reload_child_browsing_context( - Some(load_data), - NavigationType::Regular, - replace, - ); + let replace = if is_about_blank { + HistoryEntryReplacement::Enabled + } else { + HistoryEntryReplacement::Disabled + }; + self.navigate_or_reload_child_browsing_context(load_data, NavigationType::Regular, replace); } fn create_nested_browsing_context(&self) { @@ -296,6 +300,7 @@ impl HTMLIFrameElement { let window = window_from_node(self); let pipeline_id = Some(window.upcast::<GlobalScope>().pipeline_id()); let load_data = LoadData::new( + LoadOrigin::Script(document.origin().immutable().clone()), url, pipeline_id, Some(Referrer::ReferrerUrl(document.url().clone())), @@ -309,9 +314,9 @@ impl HTMLIFrameElement { .set(Some(top_level_browsing_context_id)); self.browsing_context_id.set(Some(browsing_context_id)); self.navigate_or_reload_child_browsing_context( - Some(load_data), + load_data, NavigationType::InitialAboutBlank, - false, + HistoryEntryReplacement::Disabled, ); } |