Skip to content

Commit 94b613f

Browse files
authored
Auto merge of #28536 - yvt:fix-one-compartment, r=jdm
Create only one compartment for each script thread (agent) Documents in the same [agent][1] can share and exchange JS and DOM objects freely, so putting them in separate compartments would require almost every instance of `Dom` to be capable of handling cross-compartment references. [1]: https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-agent-formalism --- - [x] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #___ (GitHub issue number if applicable) --- - [ ] There are tests for these changes OR - [x] These changes do not require tests because I think there's already a wide test coverage for same-origin-domain JS object passing, albeit this requires Servo to be built with `--debug-mozjs` for the errors to be (reliably) observable
2 parents 42d7892 + 7cda260 commit 94b613f

File tree

18 files changed

+52
-77
lines changed

18 files changed

+52
-77
lines changed

components/script/dom/bindings/interface.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ use js::glue::UncheckedUnwrapObject;
1616
use js::jsapi::GetWellKnownSymbol;
1717
use js::jsapi::HandleObject as RawHandleObject;
1818
use js::jsapi::{jsid, JSClass, JSClassOps};
19+
use js::jsapi::{
20+
Compartment, CompartmentSpecifier, IsSharableCompartment, IsSystemCompartment,
21+
JS_IterateCompartments, JS::CompartmentIterResult,
22+
};
1923
use js::jsapi::{JSAutoRealm, JSContext, JSFunctionSpec, JSObject, JSFUN_CONSTRUCTOR};
2024
use js::jsapi::{JSPropertySpec, JSString, JSTracer, JS_AtomizeAndPinString};
2125
use js::jsapi::{JS_GetFunctionObject, JS_NewFunction, JS_NewGlobalObject};
@@ -139,6 +143,7 @@ pub unsafe fn create_global_object(
139143
options.creationOptions_.traceGlobal_ = Some(trace);
140144
options.creationOptions_.sharedMemoryAndAtomics_ = false;
141145
options.creationOptions_.streams_ = true;
146+
select_compartment(cx, &mut options);
142147

143148
rval.set(JS_NewGlobalObject(
144149
*cx,
@@ -162,6 +167,43 @@ pub unsafe fn create_global_object(
162167
JS_FireOnNewGlobalObject(*cx, rval.handle());
163168
}
164169

170+
/// Choose the compartment to create a new global object in.
171+
fn select_compartment(cx: SafeJSContext, options: &mut RealmOptions) {
172+
type Data = *mut Compartment;
173+
unsafe extern "C" fn callback(
174+
_cx: *mut JSContext,
175+
data: *mut libc::c_void,
176+
compartment: *mut Compartment,
177+
) -> CompartmentIterResult {
178+
let data = data as *mut Data;
179+
180+
if !IsSharableCompartment(compartment) || IsSystemCompartment(compartment) {
181+
return CompartmentIterResult::KeepGoing;
182+
}
183+
184+
// Choose any sharable, non-system compartment in this context to allow
185+
// same-agent documents to share JS and DOM objects.
186+
*data = compartment;
187+
CompartmentIterResult::Stop
188+
}
189+
190+
let mut compartment: Data = ptr::null_mut();
191+
unsafe {
192+
JS_IterateCompartments(
193+
*cx,
194+
(&mut compartment) as *mut Data as *mut libc::c_void,
195+
Some(callback),
196+
);
197+
}
198+
199+
if compartment.is_null() {
200+
options.creationOptions_.compSpec_ = CompartmentSpecifier::NewCompartmentAndZone;
201+
} else {
202+
options.creationOptions_.compSpec_ = CompartmentSpecifier::ExistingCompartment;
203+
options.creationOptions_.__bindgen_anon_1.comp_ = compartment;
204+
}
205+
}
206+
165207
/// Create and define the interface object of a callback interface.
166208
pub fn create_callback_interface_object(
167209
cx: SafeJSContext,

components/script/dom/windowproxy.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -637,13 +637,11 @@ impl WindowProxy {
637637
// The old window proxy no longer owns this browsing context.
638638
SetProxyReservedSlot(old_js_proxy.get(), 0, &PrivateValue(ptr::null_mut()));
639639

640-
// Brain transpant the window proxy.
641-
// We need to do this, because the Window and WindowProxy
642-
// objects need to be in the same realm.
643-
// JS_TransplantObject does this by copying the contents
644-
// of the old window proxy to the new window proxy, then
645-
// making the old window proxy a cross-realm wrapper
646-
// pointing to the new window proxy.
640+
// Brain transpant the window proxy. Brain transplantation is
641+
// usually done to move a window proxy between compartments, but
642+
// that's not what we are doing here. We need to do this just
643+
// because we want to replace the wrapper's `ProxyTraps`, but we
644+
// don't want to update its identity.
647645
rooted!(in(*cx) let new_js_proxy = NewWindowProxy(*cx, window_jsobject, handler));
648646
debug!(
649647
"Transplanting proxy from {:p} to {:p}.",
Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,4 @@
11
[event-global-extra.window.html]
2-
[window.event for constructors from another global: EventTarget]
3-
expected: FAIL
4-
5-
[window.event for constructors from another global: XMLHttpRequest]
6-
expected: FAIL
7-
8-
[window.event and element from another document]
9-
expected: FAIL
10-
11-
[window.event and moving an element post-dispatch]
12-
expected: FAIL
13-
142
[window.event should not be affected by nodes moving post-dispatch]
153
expected: FAIL
164

17-
[Listener from a different global]
18-
expected: FAIL
19-

tests/wpt/metadata/encoding/single-byte-decoder.html.ini

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
type: testharness
33

44
[single-byte-decoder.html?document]
5-
expected: TIMEOUT
65
[ISO-8859-4: iso_8859-4:1988 (document.characterSet and document.inputEncoding)]
76
expected: FAIL
87

@@ -30,9 +29,6 @@
3029
[ISO-8859-8: iso_8859-8:1988 (document.characterSet and document.inputEncoding)]
3130
expected: FAIL
3231

33-
[KOI8-R: cskoi8r (document.characterSet and document.inputEncoding)]
34-
expected: TIMEOUT
35-
3632

3733
[single-byte-decoder.html?XMLHttpRequest]
3834
[ISO-8859-2: iso_8859-2:1987 (XMLHttpRequest)]

tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html.ini

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,3 @@
55
[Test javascript URL string return values in direct and indirect (target) frame contexts. 9]
66
expected: FAIL
77

8-
[Test javascript URL string return values in direct and indirect (target) frame contexts. 5]
9-
expected: FAIL
10-
11-
[Test javascript URL string return values in direct and indirect (target) frame contexts. 6]
12-
expected: FAIL
13-
14-
[Test javascript URL string return values in direct and indirect (target) frame contexts. 7]
15-
expected: FAIL
16-
17-
[Test javascript URL string return values in direct and indirect (target) frame contexts. 8]
18-
expected: FAIL
19-

tests/wpt/metadata/html/browsers/origin/cross-origin-objects/cross-origin-objects-on-new-window.html.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/metadata/html/browsers/sandboxing/sandbox-disallow-same-origin.html.ini

Lines changed: 0 additions & 4 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
[creating_browsing_context_test_01.html]
2-
expected: TIMEOUT
32
[first argument: absolute url]
4-
expected: TIMEOUT
3+
expected: FAIL
54

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[iframe_sandbox_popups_escaping-2.html]
2-
expected: TIMEOUT
2+
expected: CRASH
33
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
44
expected: TIMEOUT
55

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[iframe_sandbox_popups_nonescaping-1.html]
22
type: testharness
3-
expected: TIMEOUT
3+
expected: CRASH
44
[Check that popups from a sandboxed iframe do not escape the sandbox]
55
expected: NOTRUN
66

0 commit comments

Comments
 (0)