mirror of
https://github.com/lexmount/moli.git
synced 2026-09-29 00:01:38 +00:00
fix(window): make WindowProxy prototypes immutable
This commit is contained in:
@@ -2924,7 +2924,6 @@ html/browsers/the-window-object/window-indexed-properties-strict.html
|
||||
html/browsers/the-window-object/window-indexed-properties.html
|
||||
html/browsers/the-window-object/window-open-noopener.html?indexed
|
||||
html/browsers/the-window-object/window-open-noreferrer.html
|
||||
html/browsers/the-windowproxy-exotic-object/windowproxy-prototype-setting-same-origin.html
|
||||
html/browsers/windows/browsing-context-names/choose-default-001.html
|
||||
html/browsers/windows/browsing-context.html
|
||||
html/browsers/windows/document-domain-removed-iframe.html
|
||||
|
||||
@@ -5248,6 +5248,7 @@ html/browsers/the-window-object/window-open-noopener.html?_top
|
||||
html/browsers/the-window-object/window-prototype-chain.html
|
||||
html/browsers/the-windowproxy-exotic-object/windowproxy-define-own-property-unforgeable-same-origin.html
|
||||
html/browsers/the-windowproxy-exotic-object/windowproxy-prevent-extensions.html
|
||||
html/browsers/the-windowproxy-exotic-object/windowproxy-prototype-setting-same-origin.html
|
||||
html/browsers/windows/browsing-context-names/choose-_blank-001.html
|
||||
html/browsers/windows/browsing-context-names/choose-default-002.html
|
||||
html/browsers/windows/browsing-context-window.html
|
||||
|
||||
@@ -42,6 +42,14 @@ impl ContextBootstrapAssets {
|
||||
.id_by_name("Window")
|
||||
.ok_or_else(|| anyhow!("missing constructor template metadata `Window`"))?;
|
||||
let window_template = registry.get_or_build_template(scope, window_id)?;
|
||||
// WindowProxy's [[SetPrototypeOf]] only succeeds when the requested
|
||||
// prototype is already its current prototype. Set the invariant on
|
||||
// Window's instance template before deriving the same- and
|
||||
// cross-origin global templates so it remains attached to V8's global
|
||||
// proxy rather than only to the inner global object.
|
||||
window_template
|
||||
.instance_template(scope)
|
||||
.set_immutable_proto();
|
||||
// A cross-origin WindowProxy shell must retain Window's V8 wrapper
|
||||
// identity so that detaching and reusing it for the committed child
|
||||
// realm discards the facade's temporary own properties. It must not,
|
||||
|
||||
@@ -8827,6 +8827,72 @@ fn window_named_properties_respect_later_prototype_properties_and_descriptor_fla
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn main_and_child_window_proxies_have_immutable_prototypes() {
|
||||
let mut vm = new_storage_test_vm("https://window-proxy-prototype.test/");
|
||||
|
||||
let result = vm
|
||||
.eval(
|
||||
r#"
|
||||
(() => {
|
||||
"use strict";
|
||||
const frame = document.createElement("iframe");
|
||||
(document.body || document.documentElement || document).appendChild(frame);
|
||||
|
||||
const probe = target => {
|
||||
const original = Object.getPrototypeOf(target);
|
||||
const replacement = {};
|
||||
const outcome = callback => {
|
||||
try {
|
||||
callback();
|
||||
return "returned";
|
||||
} catch (error) {
|
||||
return error && error.name;
|
||||
}
|
||||
};
|
||||
|
||||
const objectDifferent = outcome(() => {
|
||||
Object.setPrototypeOf(target, replacement);
|
||||
});
|
||||
const dunderDifferent = outcome(() => {
|
||||
target.__proto__ = replacement;
|
||||
});
|
||||
const reflectDifferent = Reflect.setPrototypeOf(target, replacement);
|
||||
const unchanged = Object.getPrototypeOf(target) === original;
|
||||
const objectSame = Object.setPrototypeOf(target, original) === target;
|
||||
const dunderSame = outcome(() => {
|
||||
target.__proto__ = original;
|
||||
});
|
||||
const reflectSame = Reflect.setPrototypeOf(target, original);
|
||||
|
||||
return {
|
||||
objectDifferent,
|
||||
dunderDifferent,
|
||||
reflectDifferent,
|
||||
unchanged,
|
||||
objectSame,
|
||||
dunderSame,
|
||||
reflectSame,
|
||||
};
|
||||
};
|
||||
|
||||
const observations = {
|
||||
main: probe(window),
|
||||
child: probe(frame.contentWindow),
|
||||
};
|
||||
frame.remove();
|
||||
return JSON.stringify(observations);
|
||||
})()
|
||||
"#,
|
||||
)
|
||||
.expect("WindowProxy immutable prototype probe should evaluate");
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
r#"{"main":{"objectDifferent":"TypeError","dunderDifferent":"TypeError","reflectDifferent":false,"unchanged":true,"objectSame":true,"dunderSame":"returned","reflectSame":true},"child":{"objectDifferent":"TypeError","dunderDifferent":"TypeError","reflectDifferent":false,"unchanged":true,"objectSame":true,"dunderSame":"returned","reflectSame":true}}"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn window_internal_child_context_identity_is_not_read_from_web_properties() {
|
||||
let mut vm = new_storage_test_vm("https://window-private-identity.test/");
|
||||
|
||||
Reference in New Issue
Block a user