aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/proxyhandler.rs
diff options
context:
space:
mode:
authoryvt <i@yvt.jp>2021-07-17 13:31:39 +0900
committeryvt <i@yvt.jp>2021-07-17 15:26:15 +0900
commit4bc345317439f8eabd4f1e4817407d2f62cebf6c (patch)
tree69fa8a260f5c3557c49259db6ffe5ac4549dbd1b /components/script/dom/bindings/proxyhandler.rs
parent80cda12a87aecdcdfd7e1fca3e7f172933e710e9 (diff)
downloadservo-4bc345317439f8eabd4f1e4817407d2f62cebf6c.tar.gz
servo-4bc345317439f8eabd4f1e4817407d2f62cebf6c.zip
feat(script): Implement `[[Set]]` for `Location`
Diffstat (limited to 'components/script/dom/bindings/proxyhandler.rs')
-rw-r--r--components/script/dom/bindings/proxyhandler.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs
index cbe97d66b9a..b460106af0d 100644
--- a/components/script/dom/bindings/proxyhandler.rs
+++ b/components/script/dom/bindings/proxyhandler.rs
@@ -436,12 +436,78 @@ pub unsafe fn cross_origin_get(
)
}
+/// Implementation of [`CrossOriginSet`].
+///
+/// [`CrossOriginSet`]: https://html.spec.whatwg.org/multipage/#crossoriginset-(-o,-p,-v,-receiver-)
+pub unsafe fn cross_origin_set(
+ cx: SafeJSContext,
+ proxy: RawHandleObject,
+ id: RawHandleId,
+ v: RawHandleValue,
+ receiver: RawHandleValue,
+ result: *mut ObjectOpResult,
+) -> bool {
+ // > 1. Let desc be ? O.[[GetOwnProperty]](P).
+ rooted!(in(*cx) let mut descriptor = PropertyDescriptor::default());
+ if !InvokeGetOwnPropertyDescriptor(
+ GetProxyHandler(*proxy),
+ *cx,
+ proxy,
+ id,
+ descriptor.handle_mut().into(),
+ ) {
+ return false;
+ }
+
+ // > 2. Assert: desc is not undefined.
+ assert!(
+ !descriptor.obj.is_null(),
+ "Callees should throw in all cases when they are not finding \
+ a property decriptor"
+ );
+
+ // > 3. If desc.[[Set]] is present and its value is not undefined,
+ // > then: [...]
+ rooted!(in(*cx) let mut setter = ptr::null_mut::<JSObject>());
+ get_setter_object(&descriptor, setter.handle_mut().into());
+ if setter.get().is_null() {
+ // > 4. Throw a "SecurityError" DOMException.
+ return report_cross_origin_denial(cx, id, "set");
+ }
+
+ rooted!(in(*cx) let mut setter_jsval = UndefinedValue());
+ setter.get().to_jsval(*cx, setter_jsval.handle_mut());
+
+ // > 3.1. Perform ? Call(setter, Receiver, «V»).
+ // >
+ // > 3.2. Return true.
+ rooted!(in(*cx) let mut ignored = UndefinedValue());
+ if !jsapi::Call(
+ *cx,
+ receiver,
+ setter_jsval.handle().into(),
+ &jsapi::HandleValueArray::from_rooted_slice(&[v.get()]),
+ ignored.handle_mut().into(),
+ ) {
+ return false;
+ }
+
+ (*result).code_ = 0 /* OkCode */;
+ true
+}
+
unsafe fn get_getter_object(d: &PropertyDescriptor, out: RawMutableHandleObject) {
if (d.attrs & jsapi::JSPROP_GETTER as u32) != 0 {
out.set(std::mem::transmute(d.getter));
}
}
+unsafe fn get_setter_object(d: &PropertyDescriptor, out: RawMutableHandleObject) {
+ if (d.attrs & jsapi::JSPROP_SETTER as u32) != 0 {
+ out.set(std::mem::transmute(d.setter));
+ }
+}
+
/// <https://tc39.es/ecma262/#sec-isaccessordescriptor>
fn is_accessor_descriptor(d: &PropertyDescriptor) -> bool {
d.attrs & (jsapi::JSPROP_GETTER as u32 | jsapi::JSPROP_SETTER as u32) != 0