diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs index 9f0be02e4842e..5e523d6982a4c 100644 --- a/components/script/dom/browsingcontext.rs +++ b/components/script/dom/browsingcontext.rs @@ -3,13 +3,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; +use dom::bindings::error::{Error, throw_dom_exception}; +use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root, RootedReference}; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use dom::bindings::reflector::{DomObject, Reflector}; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::WindowProxyHandler; use dom::bindings::utils::get_array_index_from_id; +use dom::dissimilaroriginwindow::DissimilarOriginWindow; use dom::element::Element; +use dom::globalscope::GlobalScope; use dom::window::Window; use js::JSCLASS_IS_GLOBAL; use js::glue::{CreateWrapperProxyHandler, ProxyTraps, NewWindowProxy}; @@ -18,12 +22,13 @@ use js::jsapi::{Handle, HandleId, HandleObject, HandleValue}; use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; use js::jsapi::{JSPROP_READONLY, JSTracer, JS_DefinePropertyById}; use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; -use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_HasPropertyById}; -use js::jsapi::{JS_TransplantObject, SetWindowProxy}; +use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_HasPropertyById, JS_HasOwnPropertyById}; +use js::jsapi::{JS_IsExceptionPending, JS_TransplantObject, SetWindowProxy}; use js::jsapi::{MutableHandle, MutableHandleObject, MutableHandleValue}; use js::jsapi::{ObjectOpResult, PropertyDescriptor}; use js::jsval::{UndefinedValue, PrivateValue}; use js::rust::get_object_class; +use msg::constellation_msg::PipelineId; use std::cell::Cell; use std::ptr; @@ -39,6 +44,13 @@ pub struct BrowsingContext { /// changes Window. reflector: Reflector, + /// The pipeline id of the currently active document. + /// May be None, when the currently active document is in another script thread. + /// We do not try to keep the pipeline id for documents in other threads, + /// as this would require the constellation notifying many script threads about + /// the change, which could be expensive. + currently_active: Cell>, + /// Has this browsing context been discarded? discarded: Cell, @@ -47,9 +59,10 @@ pub struct BrowsingContext { } impl BrowsingContext { - pub fn new_inherited(frame_element: Option<&Element>) -> BrowsingContext { + pub fn new_inherited(currently_active: PipelineId, frame_element: Option<&Element>) -> BrowsingContext { BrowsingContext { reflector: Reflector::new(), + currently_active: Cell::new(Some(currently_active)), discarded: Cell::new(false), frame_element: frame_element.map(JS::from_ref), } @@ -72,7 +85,8 @@ impl BrowsingContext { assert!(!window_proxy.is_null()); // Create a new browsing context. - let mut browsing_context = box BrowsingContext::new_inherited(frame_element); + let currently_active = window.global().pipeline_id(); + let mut browsing_context = box BrowsingContext::new_inherited(currently_active, frame_element); // The window proxy owns the browsing context. // When we finalize the window proxy, it drops the browsing context it owns. @@ -104,10 +118,10 @@ impl BrowsingContext { /// Change the Window that this browsing context's WindowProxy resolves to. // TODO: support setting the window proxy to a dummy value, // to handle the case when the active document is in another script thread. - pub fn set_window_proxy(&self, window: &Window) { + fn set_window_proxy(&self, window: &GlobalScope, traps: &ProxyTraps) { unsafe { debug!("Setting window proxy of {:p}.", self); - let WindowProxyHandler(handler) = window.windowproxy_handler(); + let handler = CreateWrapperProxyHandler(traps); assert!(!handler.is_null()); let cx = window.get_cx(); @@ -144,6 +158,22 @@ impl BrowsingContext { } } + pub fn set_currently_active(&self, window: &Window) { + let globalscope = window.upcast(); + self.set_window_proxy(&*globalscope, &PROXY_HANDLER); + self.currently_active.set(Some(globalscope.pipeline_id())); + } + + pub fn unset_currently_active(&self) { + let window = DissimilarOriginWindow::new(self); + self.set_window_proxy(&*window.upcast(), &XORIGIN_PROXY_HANDLER); + self.currently_active.set(None); + } + + pub fn currently_active(&self) -> Option { + self.currently_active.get() + } + pub fn window_proxy(&self) -> *mut JSObject { let window_proxy = self.reflector.get_jsobject(); assert!(!window_proxy.get().is_null()); @@ -332,6 +362,145 @@ static PROXY_HANDLER: ProxyTraps = ProxyTraps { isConstructor: None, }; +#[allow(unsafe_code)] +pub fn new_window_proxy_handler() -> WindowProxyHandler { + unsafe { + WindowProxyHandler(CreateWrapperProxyHandler(&PROXY_HANDLER)) + } +} + +// The proxy traps for cross-origin windows. +// These traps often throw security errors, and only pass on calls to methods +// defined in the DissimilarOriginWindow IDL. + +#[allow(unsafe_code)] +unsafe fn throw_security_error(cx: *mut JSContext) -> bool { + if !JS_IsExceptionPending(cx) { + let global = GlobalScope::from_context(cx); + throw_dom_exception(cx, &*global, Error::Security); + } + false +} + +#[allow(unsafe_code)] +unsafe extern "C" fn has_xorigin(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + bp: *mut bool) + -> bool +{ + rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let mut found = false; + JS_HasOwnPropertyById(cx, target.handle(), id, &mut found); + if found { + *bp = true; + true + } else { + throw_security_error(cx) + } +} + +#[allow(unsafe_code)] +unsafe extern "C" fn get_xorigin(cx: *mut JSContext, + proxy: HandleObject, + receiver: HandleValue, + id: HandleId, + vp: MutableHandleValue) + -> bool +{ + let mut found = false; + has_xorigin(cx, proxy, id, &mut found); + found && get(cx, proxy, receiver, id, vp) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn set_xorigin(cx: *mut JSContext, + _: HandleObject, + _: HandleId, + _: HandleValue, + _: HandleValue, + _: *mut ObjectOpResult) + -> bool +{ + throw_security_error(cx) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn delete_xorigin(cx: *mut JSContext, + _: HandleObject, + _: HandleId, + _: *mut ObjectOpResult) + -> bool +{ + throw_security_error(cx) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn getOwnPropertyDescriptor_xorigin(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + desc: MutableHandle) + -> bool +{ + let mut found = false; + has_xorigin(cx, proxy, id, &mut found); + found && getOwnPropertyDescriptor(cx, proxy, id, desc) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn defineProperty_xorigin(cx: *mut JSContext, + _: HandleObject, + _: HandleId, + _: Handle, + _: *mut ObjectOpResult) + -> bool +{ + throw_security_error(cx) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn preventExtensions_xorigin(cx: *mut JSContext, + _: HandleObject, + _: *mut ObjectOpResult) + -> bool +{ + throw_security_error(cx) +} + +static XORIGIN_PROXY_HANDLER: ProxyTraps = ProxyTraps { + enter: None, + getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor_xorigin), + defineProperty: Some(defineProperty_xorigin), + ownPropertyKeys: None, + delete_: Some(delete_xorigin), + enumerate: None, + getPrototypeIfOrdinary: None, + preventExtensions: Some(preventExtensions_xorigin), + isExtensible: None, + has: Some(has_xorigin), + get: Some(get_xorigin), + set: Some(set_xorigin), + call: None, + construct: None, + getPropertyDescriptor: Some(getOwnPropertyDescriptor_xorigin), + hasOwn: Some(has_xorigin), + getOwnEnumerablePropertyKeys: None, + nativeCall: None, + hasInstance: None, + objectClassIs: None, + className: None, + fun_toString: None, + boxedValue_unbox: None, + defaultValue: None, + trace: Some(trace), + finalize: Some(finalize), + objectMoved: None, + isCallable: None, + isConstructor: None, +}; + +// How WindowProxy objects are garbage collected. + #[allow(unsafe_code)] unsafe extern fn finalize(_fop: *mut JSFreeOp, obj: *mut JSObject) { let this = GetProxyExtra(obj, 0).to_private() as *mut BrowsingContext; @@ -354,9 +523,3 @@ unsafe extern fn trace(trc: *mut JSTracer, obj: *mut JSObject) { (*this).trace(trc); } -#[allow(unsafe_code)] -pub fn new_window_proxy_handler() -> WindowProxyHandler { - unsafe { - WindowProxyHandler(CreateWrapperProxyHandler(&PROXY_HANDLER)) - } -} diff --git a/components/script/dom/dissimilaroriginlocation.rs b/components/script/dom/dissimilaroriginlocation.rs new file mode 100644 index 0000000000000..6f5eda8c40250 --- /dev/null +++ b/components/script/dom/dissimilaroriginlocation.rs @@ -0,0 +1,80 @@ +/* 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::DissimilarOriginLocationBinding; +use dom::bindings::codegen::Bindings::DissimilarOriginLocationBinding::DissimilarOriginLocationMethods; +use dom::bindings::error::{Error, ErrorResult, Fallible}; +use dom::bindings::js::{JS, Root}; +use dom::bindings::reflector::Reflector; +use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::str::DOMString; +use dom::bindings::str::USVString; +use dom::dissimilaroriginwindow::DissimilarOriginWindow; + +/// Represents a dissimilar-origin `Location` that exists in another script thread. +/// +/// Since the `Location` is in a different script thread, we cannot access it +/// directly, but some of its accessors (for example setting `location.href`) +/// still need to function. + +#[dom_struct] +pub struct DissimilarOriginLocation { + /// The reflector. Once we have XOWs, this will have a cross-origin + /// wrapper placed around it. + reflector: Reflector, + + /// The window associated with this location. + window: JS, +} + +impl DissimilarOriginLocation { + #[allow(unrooted_must_root)] + fn new_inherited(window: &DissimilarOriginWindow) -> DissimilarOriginLocation { + DissimilarOriginLocation { + reflector: Reflector::new(), + window: JS::from_ref(window), + } + } + + pub fn new(window: &DissimilarOriginWindow) -> Root { + reflect_dom_object(box DissimilarOriginLocation::new_inherited(window), + window, + DissimilarOriginLocationBinding::Wrap) + } +} + +impl DissimilarOriginLocationMethods for DissimilarOriginLocation { + // https://html.spec.whatwg.org/multipage/#dom-location-href + fn GetHref(&self) -> Fallible { + Err(Error::Security) + } + + // https://html.spec.whatwg.org/multipage/#dom-location-href + fn SetHref(&self, _: USVString) -> ErrorResult { + // TODO: setting href on a cross-origin window should succeed? + Err(Error::Security) + } + + // https://html.spec.whatwg.org/multipage/#dom-location-assign + fn Assign(&self, _: USVString) -> Fallible<()> { + // TODO: setting href on a cross-origin window should succeed? + Err(Error::Security) + } + + // https://html.spec.whatwg.org/multipage/#dom-location-replace + fn Replace(&self, _: USVString) -> Fallible<()> { + // TODO: replacing href on a cross-origin window should succeed? + Err(Error::Security) + } + + // https://html.spec.whatwg.org/multipage/#dom-location-reload + fn Reload(&self) -> Fallible<()> { + Err(Error::Security) + } + + // https://html.spec.whatwg.org/multipage/#dom-location-href + fn Stringifier(&self) -> Fallible { + Err(Error::Security) + } +} diff --git a/components/script/dom/dissimilaroriginwindow.rs b/components/script/dom/dissimilaroriginwindow.rs new file mode 100644 index 0000000000000..518adb0f34167 --- /dev/null +++ b/components/script/dom/dissimilaroriginwindow.rs @@ -0,0 +1,140 @@ +/* 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::js::{JS, MutNullableJS, Root}; +use dom::bindings::reflector::DomObject; +use dom::bindings::str::DOMString; +use dom::browsingcontext::BrowsingContext; +use dom::dissimilaroriginlocation::DissimilarOriginLocation; +use dom::globalscope::GlobalScope; +use ipc_channel::ipc; +use js::jsapi::{JSContext, HandleValue}; +use js::jsval::{JSVal, UndefinedValue}; +use msg::constellation_msg::PipelineId; + +/// Represents a dissimilar-origin `Window` that exists in another script thread. +/// +/// Since the `Window` is in a different script thread, we cannot access it +/// 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, +/// that throws security exceptions for most accessors. This is not a replacement +/// for XOWs, but provides belt-and-braces security. +#[dom_struct] +pub struct DissimilarOriginWindow { + /// The global for this window. + globalscope: GlobalScope, + + /// The browsing context this window is part of. + browsing_context: JS, + + /// The location of this window, initialized lazily. + location: MutNullableJS, +} + +impl DissimilarOriginWindow { + #[allow(unsafe_code)] + pub fn new(browsing_context: &BrowsingContext) -> Root { + let globalscope = browsing_context.global(); + let cx = globalscope.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(), + globalscope.devtools_chan().cloned(), + globalscope.mem_profiler_chan().clone(), + globalscope.time_profiler_chan().clone(), + globalscope.constellation_chan().clone(), + globalscope.scheduler_chan().clone(), + globalscope.resource_threads().clone(), + timer_event_chan), + browsing_context: JS::from_ref(browsing_context), + location: MutNullableJS::new(None), + }; + unsafe { DissimilarOriginWindowBinding::Wrap(cx, win) } + } +} + +impl DissimilarOriginWindowMethods for DissimilarOriginWindow { + // https://html.spec.whatwg.org/multipage/#dom-window + fn Window(&self) -> Root { + Root::from_ref(&*self.browsing_context) + } + + // https://html.spec.whatwg.org/multipage/#dom-self + fn Self_(&self) -> Root { + Root::from_ref(&*self.browsing_context) + } + + // https://html.spec.whatwg.org/multipage/#dom-frames + fn Frames(&self) -> Root { + Root::from_ref(&*self.browsing_context) + } + + // https://html.spec.whatwg.org/multipage/#dom-parent + fn GetParent(&self) -> Option> { + // TODO: implement window.parent correctly for x-origin windows. + Some(Root::from_ref(&*self.browsing_context)) + } + + // https://html.spec.whatwg.org/multipage/#dom-top + fn GetTop(&self) -> Option> { + // TODO: implement window.top correctly for x-origin windows. + Some(Root::from_ref(&*self.browsing_context)) + } + + // https://html.spec.whatwg.org/multipage/#dom-length + fn Length(&self) -> u32 { + // TODO: Implement x-origin length + 0 + } + + // https://html.spec.whatwg.org/multipage/#dom-window-close + fn Close(&self) { + // TODO: Implement x-origin close + } + + // https://html.spec.whatwg.org/multipage/#dom-window-closed + fn Closed(&self) -> bool { + // TODO: Implement x-origin close + false + } + + #[allow(unsafe_code)] + // https://html.spec.whatwg.org/multipage/#dom-window-postmessage + unsafe fn PostMessage(&self, _: *mut JSContext, _: HandleValue, _: DOMString) { + // TODO: Implement x-origin postMessage + } + + #[allow(unsafe_code)] + // https://html.spec.whatwg.org/multipage/#dom-opener + unsafe fn Opener(&self, _: *mut 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) { + // TODO: Implement x-origin opener + } + + // https://html.spec.whatwg.org/multipage/#dom-window-blur + fn Blur(&self) { + // TODO: Implement x-origin blur + } + + // https://html.spec.whatwg.org/multipage/#dom-focus + fn Focus(&self) { + // TODO: Implement x-origin focus + } + + // https://html.spec.whatwg.org/multipage/#dom-location + fn Location(&self) -> Root { + self.location.or_init(|| DissimilarOriginLocation::new(self)) + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 4b3c0c02cbbf3..7b96ea2523d88 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -258,6 +258,8 @@ pub mod csssupportsrule; pub mod cssviewportrule; pub mod customevent; pub mod dedicatedworkerglobalscope; +pub mod dissimilaroriginlocation; +pub mod dissimilaroriginwindow; pub mod document; pub mod documentfragment; pub mod documenttype; diff --git a/components/script/dom/webidls/DissimilarOriginLocation.webidl b/components/script/dom/webidls/DissimilarOriginLocation.webidl new file mode 100644 index 0000000000000..8eca6a790acc2 --- /dev/null +++ b/components/script/dom/webidls/DissimilarOriginLocation.webidl @@ -0,0 +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/. */ + + +// This is a Servo-specific interface, used to represent locations +// that are not similar-origin, so live in another script thread. +// It is based on the interface for Window, but only contains the +// accessors that do not throw security exceptions when called +// cross-origin. +// +// Note that similar-origin locations are kept in the same script +// thread, so this mechanism cannot be relied upon as the only +// way to enforce security policy. + +// https://html.spec.whatwg.org/multipage/#location +[Unforgeable, NoInterfaceObject] interface DissimilarOriginLocation { + [Throws] attribute USVString href; + [Throws] void assign(USVString url); + [Throws] void replace(USVString url); + [Throws] void reload(); + [Throws] stringifier; + + // TODO: finish this interface +}; diff --git a/components/script/dom/webidls/DissimilarOriginWindow.webidl b/components/script/dom/webidls/DissimilarOriginWindow.webidl new file mode 100644 index 0000000000000..6aeb5c7d1b220 --- /dev/null +++ b/components/script/dom/webidls/DissimilarOriginWindow.webidl @@ -0,0 +1,32 @@ +/* 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/. */ + +// This is a Servo-specific interface, used to represent windows +// that are not similar-origin, so live in another script thread. +// It is based on the interface for Window, but only contains the +// accessors that do not throw security exceptions when called +// cross-origin. +// +// Note that similar-origin windows are kept in the same script +// thread, so this mechanism cannot be relied upon as the only +// way to enforce security policy. + +// https://html.spec.whatwg.org/multipage/#window +[Global, NoInterfaceObject] +interface DissimilarOriginWindow : GlobalScope { + [Unforgeable] readonly attribute WindowProxy window; + [BinaryName="Self_", Replaceable] readonly attribute WindowProxy self; + [Unforgeable] readonly attribute WindowProxy? parent; + [Unforgeable] readonly attribute WindowProxy? top; + [Replaceable] readonly attribute WindowProxy frames; + [Replaceable] readonly attribute unsigned long length; + [Unforgeable] readonly attribute DissimilarOriginLocation location; + + void close(); + readonly attribute boolean closed; + void postMessage(any message, DOMString targetOrigin); + attribute any opener; + void blur(); + void focus(); +}; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index d1eba0245e0c6..1fbe57ba16510 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -1514,7 +1514,10 @@ impl Window { // Suspend timer events. self.upcast::().suspend(); - // TODO: set the window proxy to resolve to an object which throws security errors. #15233 + // Set the window proxy to be a cross-origin window. + if self.browsing_context().currently_active() == Some(self.global().pipeline_id()) { + self.browsing_context().unset_currently_active(); + } // A hint to the JS runtime that now would be a good time to // GC any unreachable objects generated by user script, @@ -1528,7 +1531,7 @@ impl Window { self.upcast::().resume(); // Set the window proxy to be this object. - self.browsing_context().set_window_proxy(&self); + self.browsing_context().set_currently_active(self); // Push the document title to the compositor since we are // activating this document due to a navigation. diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index fa83eaed63191..ac093a7a5df9e 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1678,7 +1678,7 @@ impl ScriptThread { }, hash_map::Entry::Occupied(entry) => { let browsing_context = entry.get(); - browsing_context.set_window_proxy(&window); + browsing_context.set_currently_active(&*window); window.init_browsing_context(browsing_context); }, } @@ -1782,7 +1782,9 @@ impl ScriptThread { ServoParser::parse_html_document(&document, parse_input, final_url); } - if incomplete.activity != DocumentActivity::FullyActive { + if incomplete.activity == DocumentActivity::FullyActive { + window.resume(); + } else { window.suspend(); } diff --git a/tests/wpt/metadata/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions.html.ini b/tests/wpt/metadata/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions.html.ini new file mode 100644 index 0000000000000..487bf415faf11 --- /dev/null +++ b/tests/wpt/metadata/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions.html.ini @@ -0,0 +1,47 @@ +[cross-origin-objects-exceptions.html] + type: testharness + [Basic sanity-checking] + expected: FAIL + + [Only whitelisted properties are accessible cross-origin] + expected: PASS + + [[[GetPrototypeOf\]\] should return null] + expected: FAIL + + [[[SetPrototypeOf\]\] should throw] + expected: FAIL + + [[[PreventExtensions\]\] should throw for cross-origin objects] + expected: FAIL + + [[[GetOwnProperty\]\] - Property descriptors for cross-origin properties should be set up correctly] + expected: FAIL + + [[[Delete\]\] Should throw on cross-origin objects] + expected: FAIL + + [[[DefineOwnProperty\]\] Should throw for cross-origin objects] + expected: FAIL + + [[[Enumerate\]\] should return an empty iterator] + expected: FAIL + + [[[OwnPropertyKeys\]\] should return all properties from cross-origin objects] + expected: FAIL + + [Cross-origin functions get local Function.prototype] + expected: FAIL + + [Cross-origin Window accessors get local Function.prototype] + expected: FAIL + + [Same-origin observers get different functions for cross-origin objects] + expected: FAIL + + [Same-origin observers get different accessors for cross-origin Window] + expected: FAIL + + [Same-origin observers get different accessors for cross-origin Location] + expected: FAIL + diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index c73fdd4a39073..ad2e7aa9492fb 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -12721,6 +12721,14 @@ {} ] ], + "mozilla/cross-origin-objects/cross-origin-objects.html": [ + [ + "/_mozilla/mozilla/cross-origin-objects/cross-origin-objects.html", + { + "timeout": "long" + } + ] + ], "mozilla/deterministic-raf.html": [ [ "/_mozilla/mozilla/deterministic-raf.html", @@ -25350,6 +25358,10 @@ "f1029d519aa7017a1a3d18a891a0774b9a39f847", "testharness" ], + "mozilla/cross-origin-objects/cross-origin-objects.html": [ + "7a73c49fafc945245f6a13a51dc2c5f1096bc15c", + "testharness" + ], "mozilla/details_ui_closed.html": [ "2acbe3afbec267bad4dd986803e636740a707507", "reftest" diff --git a/tests/wpt/mozilla/meta/mozilla/cross-origin-objects/cross-origin-objects.html.ini b/tests/wpt/mozilla/meta/mozilla/cross-origin-objects/cross-origin-objects.html.ini new file mode 100644 index 0000000000000..6c0df60a409b8 --- /dev/null +++ b/tests/wpt/mozilla/meta/mozilla/cross-origin-objects/cross-origin-objects.html.ini @@ -0,0 +1,5 @@ +[cross-origin-objects.html] + type: testharness + + [Parentage of cross-origin windows] + expected: FAIL diff --git a/tests/wpt/mozilla/tests/mozilla/cross-origin-objects/cross-origin-objects.html b/tests/wpt/mozilla/tests/mozilla/cross-origin-objects/cross-origin-objects.html new file mode 100644 index 0000000000000..eec9232845d12 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/cross-origin-objects/cross-origin-objects.html @@ -0,0 +1,93 @@ + + + +Cross-origin behavior of Window and Location + + + + + +
+ + +