mirror of
https://github.com/lexmount/moli.git
synced 2026-09-23 16:01:25 +00:00
fix(window): resolve named properties in the holder realm
This commit is contained in:
@@ -48,6 +48,19 @@ pub(in crate::context_bootstrap) fn window_child_context_handle<'s>(
|
||||
if marked_handle.is_some() {
|
||||
return marked_handle;
|
||||
}
|
||||
// A callback can run promise reactions from another realm before its
|
||||
// legacy dispatch marker is restored. The holder's native realm remains
|
||||
// authoritative for WindowProperties, including a top-level holder.
|
||||
if let Some(context) = receiver.get_creation_context(scope)
|
||||
&& let Some(host_ptr) = context_host_ptr_from_context_slot(context)
|
||||
&& let Some(identity) =
|
||||
unsafe { &*host_ptr }.window_execution_context_identity_for_access_check(context)
|
||||
{
|
||||
return unsafe { &*host_ptr }
|
||||
.window_execution_context_identity_is_current(identity)
|
||||
.then(|| identity.dispatch_scope().child_window())
|
||||
.flatten();
|
||||
}
|
||||
if let Some(handle) = crate::native_bridge::active_child_window_handle(scope) {
|
||||
if receiver_is_current_global {
|
||||
return Some(handle);
|
||||
@@ -76,22 +89,7 @@ pub(in crate::context_bootstrap) fn window_child_context_handle<'s>(
|
||||
}
|
||||
}
|
||||
|
||||
// WindowProperties is a per-realm prototype-chain object rather than the
|
||||
// global proxy, so it has no child-handle marker of its own. Resolve its
|
||||
// native Window identity through the creation context, mirroring Blink's
|
||||
// native DOMWindow association on WindowProperties.
|
||||
let receiver_context = receiver.get_creation_context(scope)?;
|
||||
let host_ptr = context_host_ptr_from_context_slot(receiver_context)?;
|
||||
let host = unsafe { &*host_ptr };
|
||||
let identity = host.window_execution_context_identity_for_access_check(receiver_context)?;
|
||||
if !host.window_execution_context_identity_is_current(identity) {
|
||||
return None;
|
||||
}
|
||||
match identity.dispatch_scope() {
|
||||
crate::native_bridge::OwnerDispatchScope::Child(handle) => Some(handle),
|
||||
crate::native_bridge::OwnerDispatchScope::Top
|
||||
| crate::native_bridge::OwnerDispatchScope::LightweightPopup(_) => None,
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn window_host_ptr(
|
||||
|
||||
@@ -14524,3 +14524,36 @@ fn child_browsing_context_lookup_tolerates_document_handle_cycle() {
|
||||
Some(handle)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn window_named_access_uses_its_realm_during_child_history_callbacks() {
|
||||
let mut vm = new_storage_test_vm("https://joint-history.test/parent");
|
||||
vm.eval(
|
||||
r#"
|
||||
const frame = document.createElement('iframe');
|
||||
frame.id = 'topFrame';
|
||||
frame.srcdoc = '<p id="childOnly">child</p>';
|
||||
(document.body || document.documentElement || document).appendChild(frame);
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
vm.drain_pending_child_frame_work_for_test();
|
||||
let child = vm
|
||||
._context_host
|
||||
.borrow()
|
||||
.child_browsing_context_handles_in_document_order()[0];
|
||||
let context = &vm.page_default_context as *const v8::Global<v8::Context>;
|
||||
vm.with_context_scope_by_ptr(context, |scope, _| {
|
||||
crate::native_bridge::enter_active_child_window_scope(scope, Some(child));
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
let result =
|
||||
vm.eval("[topFrame.id, typeof childOnly, frame.contentWindow.childOnly.id].join('|')");
|
||||
vm.with_context_scope_by_ptr(context, |scope, _| {
|
||||
crate::native_bridge::enter_active_child_window_scope(scope, None);
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(result.unwrap(), "topFrame|undefined|childOnly");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user