diff options
author | yvt <i@yvt.jp> | 2021-07-10 17:24:27 +0900 |
---|---|---|
committer | yvt <i@yvt.jp> | 2021-07-10 17:55:42 +0900 |
commit | 01a7de50ab1843d85295f9dccad7f4c099e7208c (patch) | |
tree | ee53fb6e8889deb7b880ee969e6c662e6128d210 /components/script/dom/dissimilaroriginwindow.rs | |
parent | ff8d2cdbbfc7a9dc7f38b7dd47cb350fde39388f (diff) | |
parent | 94b613fbdaa2b98f2179fc0bbda13c64e6fa0d38 (diff) | |
download | servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.tar.gz servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.zip |
Merge remote-tracking branch 'upstream/master' into feat-cow-infra
`tests/wpt/web-platform-tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html`
was reverted to the upstream version.
Diffstat (limited to 'components/script/dom/dissimilaroriginwindow.rs')
-rw-r--r-- | components/script/dom/dissimilaroriginwindow.rs | 229 |
1 files changed, 143 insertions, 86 deletions
diff --git a/components/script/dom/dissimilaroriginwindow.rs b/components/script/dom/dissimilaroriginwindow.rs index 0c367d8d21f..adba29c23fb 100644 --- a/components/script/dom/dissimilaroriginwindow.rs +++ b/components/script/dom/dissimilaroriginwindow.rs @@ -1,25 +1,25 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding; -use dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding::DissimilarOriginWindowMethods; -use dom::bindings::error::{Error, ErrorResult}; -use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableJS, Root}; -use dom::bindings::str::DOMString; -use dom::bindings::structuredclone::StructuredCloneData; -use dom::browsingcontext::BrowsingContext; -use dom::dissimilaroriginlocation::DissimilarOriginLocation; -use dom::globalscope::GlobalScope; + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding; +use crate::dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding::DissimilarOriginWindowMethods; +use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowPostMessageOptions; +use crate::dom::bindings::error::{Error, ErrorResult}; +use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; +use crate::dom::bindings::str::USVString; +use crate::dom::bindings::structuredclone; +use crate::dom::bindings::trace::RootedTraceableBox; +use crate::dom::dissimilaroriginlocation::DissimilarOriginLocation; +use crate::dom::globalscope::GlobalScope; +use crate::dom::windowproxy::WindowProxy; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use ipc_channel::ipc; -use js::jsapi::{JSContext, HandleValue}; +use js::jsapi::{Heap, JSObject}; use js::jsval::{JSVal, UndefinedValue}; +use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue}; use msg::constellation_msg::PipelineId; -use script_traits::ScriptMsg as ConstellationMsg; -use servo_url::ImmutableOrigin; -use servo_url::MutableOrigin; +use script_traits::{ScriptMsg, StructuredSerializedData}; use servo_url::ServoUrl; /// Represents a dissimilar-origin `Window` that exists in another script thread. @@ -28,7 +28,7 @@ use servo_url::ServoUrl; /// directly, but some of its accessors (for example `window.parent`) /// still need to function. /// -/// In `browsingcontext.rs`, we create a custom window proxy for these windows, +/// In `windowproxy.rs`, we create a custom window proxy for these windows, /// that throws security exceptions for most accessors. This is not a replacement /// for XOWs, but provides belt-and-braces security. #[dom_struct] @@ -36,80 +36,86 @@ pub struct DissimilarOriginWindow { /// The global for this window. globalscope: GlobalScope, - /// The browsing context this window is part of. - browsing_context: JS<BrowsingContext>, + /// The window proxy for this window. + window_proxy: Dom<WindowProxy>, /// The location of this window, initialized lazily. - location: MutNullableJS<DissimilarOriginLocation>, + location: MutNullableDom<DissimilarOriginLocation>, } impl DissimilarOriginWindow { #[allow(unsafe_code)] - pub fn new(global_to_clone_from: &GlobalScope, browsing_context: &BrowsingContext) -> Root<DissimilarOriginWindow> { + pub fn new(global_to_clone_from: &GlobalScope, window_proxy: &WindowProxy) -> DomRoot<Self> { let cx = global_to_clone_from.get_cx(); - // Any timer events fired on this window are ignored. - let (timer_event_chan, _) = ipc::channel().unwrap(); - let win = box DissimilarOriginWindow { - globalscope: GlobalScope::new_inherited(PipelineId::new(), - global_to_clone_from.devtools_chan().cloned(), - global_to_clone_from.mem_profiler_chan().clone(), - global_to_clone_from.time_profiler_chan().clone(), - global_to_clone_from.constellation_chan().clone(), - global_to_clone_from.scheduler_chan().clone(), - global_to_clone_from.resource_threads().clone(), - timer_event_chan, - global_to_clone_from.origin().clone()), - browsing_context: JS::from_ref(browsing_context), - location: MutNullableJS::new(None), - }; + let win = Box::new(Self { + globalscope: GlobalScope::new_inherited( + PipelineId::new(), + global_to_clone_from.devtools_chan().cloned(), + global_to_clone_from.mem_profiler_chan().clone(), + global_to_clone_from.time_profiler_chan().clone(), + global_to_clone_from.script_to_constellation_chan().clone(), + global_to_clone_from.scheduler_chan().clone(), + global_to_clone_from.resource_threads().clone(), + global_to_clone_from.origin().clone(), + global_to_clone_from.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(), + global_to_clone_from.is_headless(), + global_to_clone_from.get_user_agent(), + global_to_clone_from.wgpu_id_hub(), + Some(global_to_clone_from.is_secure_context()), + ), + window_proxy: Dom::from_ref(window_proxy), + location: Default::default(), + }); unsafe { DissimilarOriginWindowBinding::Wrap(cx, win) } } - #[allow(dead_code)] - pub fn origin(&self) -> &MutableOrigin { - self.globalscope.origin() + pub fn window_proxy(&self) -> DomRoot<WindowProxy> { + DomRoot::from_ref(&*self.window_proxy) } } impl DissimilarOriginWindowMethods for DissimilarOriginWindow { // https://html.spec.whatwg.org/multipage/#dom-window - fn Window(&self) -> Root<BrowsingContext> { - Root::from_ref(&*self.browsing_context) + fn Window(&self) -> DomRoot<WindowProxy> { + self.window_proxy() } // https://html.spec.whatwg.org/multipage/#dom-self - fn Self_(&self) -> Root<BrowsingContext> { - Root::from_ref(&*self.browsing_context) + fn Self_(&self) -> DomRoot<WindowProxy> { + self.window_proxy() } // https://html.spec.whatwg.org/multipage/#dom-frames - fn Frames(&self) -> Root<BrowsingContext> { + fn Frames(&self) -> DomRoot<WindowProxy> { println!("calling cross origin frames"); - Root::from_ref(&*self.browsing_context) + self.window_proxy() } // https://html.spec.whatwg.org/multipage/#dom-parent - fn GetParent(&self) -> Option<Root<BrowsingContext>> { + fn GetParent(&self) -> Option<DomRoot<WindowProxy>> { // Steps 1-3. - if self.browsing_context.is_discarded() { + if self.window_proxy.is_browsing_context_discarded() { return None; } // Step 4. - if let Some(parent) = self.browsing_context.parent() { - return Some(Root::from_ref(parent)); + if let Some(parent) = self.window_proxy.parent() { + return Some(DomRoot::from_ref(parent)); } // Step 5. - Some(Root::from_ref(&*self.browsing_context)) + Some(DomRoot::from_ref(&*self.window_proxy)) } // https://html.spec.whatwg.org/multipage/#dom-top - fn GetTop(&self) -> Option<Root<BrowsingContext>> { + fn GetTop(&self) -> Option<DomRoot<WindowProxy>> { // Steps 1-3. - if self.browsing_context.is_discarded() { + if self.window_proxy.is_browsing_context_discarded() { return None; } // Steps 4-5. - Some(Root::from_ref(self.browsing_context.top())) + Some(DomRoot::from_ref(self.window_proxy.top())) } // https://html.spec.whatwg.org/multipage/#dom-length @@ -129,41 +135,45 @@ impl DissimilarOriginWindowMethods for DissimilarOriginWindow { false } - #[allow(unsafe_code)] - // https://html.spec.whatwg.org/multipage/#dom-window-postmessage - unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue, origin: DOMString) -> ErrorResult { - // Step 3-5. - let origin = match &origin[..] { - "*" => None, - "/" => { - // TODO: Should be the origin of the incumbent settings object. - None - }, - url => match ServoUrl::parse(&url) { - Ok(url) => Some(url.origin()), - Err(_) => return Err(Error::Syntax), - } - }; - - // Step 1-2, 6-8. - // TODO(#12717): Should implement the `transfer` argument. - let data = try!(StructuredCloneData::write(cx, message)); - - // Step 9. - self.post_message(origin, data); - Ok(()) + /// https://html.spec.whatwg.org/multipage/#dom-window-postmessage + fn PostMessage( + &self, + cx: JSContext, + message: HandleValue, + target_origin: USVString, + transfer: CustomAutoRooterGuard<Vec<*mut JSObject>>, + ) -> ErrorResult { + self.post_message_impl(&target_origin, cx, message, transfer) + } + + /// https://html.spec.whatwg.org/multipage/#dom-window-postmessage-options + fn PostMessage_( + &self, + cx: JSContext, + message: HandleValue, + options: RootedTraceableBox<WindowPostMessageOptions>, + ) -> ErrorResult { + let mut rooted = CustomAutoRooter::new( + options + .parent + .transfer + .iter() + .map(|js: &RootedTraceableBox<Heap<*mut JSObject>>| js.get()) + .collect(), + ); + let transfer = CustomAutoRooterGuard::new(*cx, &mut rooted); + + self.post_message_impl(&options.targetOrigin, cx, message, transfer) } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener - unsafe fn Opener(&self, _: *mut JSContext) -> JSVal { + fn Opener(&self, _: JSContext) -> JSVal { // TODO: Implement x-origin opener UndefinedValue() } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener - unsafe fn SetOpener(&self, _: *mut JSContext, _: HandleValue) { + fn SetOpener(&self, _: JSContext, _: HandleValue) { // TODO: Implement x-origin opener } @@ -178,14 +188,61 @@ impl DissimilarOriginWindowMethods for DissimilarOriginWindow { } // https://html.spec.whatwg.org/multipage/#dom-location - fn Location(&self) -> Root<DissimilarOriginLocation> { - self.location.or_init(|| DissimilarOriginLocation::new(self)) + fn Location(&self) -> DomRoot<DissimilarOriginLocation> { + self.location + .or_init(|| DissimilarOriginLocation::new(self)) } } impl DissimilarOriginWindow { - pub fn post_message(&self, origin: Option<ImmutableOrigin>, data: StructuredCloneData) { - let msg = ConstellationMsg::PostMessage(self.browsing_context.frame_id(), origin, data.move_to_arraybuffer()); - let _ = self.upcast::<GlobalScope>().constellation_chan().send(msg); + /// https://html.spec.whatwg.org/multipage/#window-post-message-steps + fn post_message_impl( + &self, + target_origin: &USVString, + cx: JSContext, + message: HandleValue, + transfer: CustomAutoRooterGuard<Vec<*mut JSObject>>, + ) -> ErrorResult { + // Step 6-7. + let data = structuredclone::write(cx, message, Some(transfer))?; + + self.post_message(target_origin, data) + } + + /// https://html.spec.whatwg.org/multipage/#window-post-message-steps + pub fn post_message( + &self, + target_origin: &USVString, + data: StructuredSerializedData, + ) -> ErrorResult { + // Step 1. + let target = self.window_proxy.browsing_context_id(); + // Step 2. + let incumbent = match GlobalScope::incumbent() { + None => panic!("postMessage called with no incumbent global"), + Some(incumbent) => incumbent, + }; + + let source_origin = incumbent.origin().immutable().clone(); + + // Step 3-5. + let target_origin = match target_origin.0[..].as_ref() { + "*" => None, + "/" => Some(source_origin.clone()), + url => match ServoUrl::parse(&url) { + Ok(url) => Some(url.origin().clone()), + Err(_) => return Err(Error::Syntax), + }, + }; + let msg = ScriptMsg::PostMessage { + target, + source: incumbent.pipeline_id(), + source_origin, + target_origin, + data: data, + }; + // Step 8 + let _ = incumbent.script_to_constellation_chan().send(msg); + Ok(()) } } |