mirror of
https://github.com/lexmount/moli.git
synced 2026-10-04 16:00:47 +00:00
fix(window): reject indexed writes and definitions
This commit is contained in:
@@ -24,9 +24,10 @@ pub(super) use helpers::{
|
||||
window_child_context_handle, window_has_discarded_child_browsing_context,
|
||||
};
|
||||
pub(super) use interceptors::{
|
||||
window_indexed_property_deleter, window_indexed_property_descriptor,
|
||||
window_indexed_property_enumerator, window_indexed_property_getter,
|
||||
window_indexed_property_query, window_named_properties_indexed_property_getter,
|
||||
window_indexed_property_definer, window_indexed_property_deleter,
|
||||
window_indexed_property_descriptor, window_indexed_property_enumerator,
|
||||
window_indexed_property_getter, window_indexed_property_query, window_indexed_property_setter,
|
||||
window_named_properties_indexed_property_getter,
|
||||
window_named_properties_indexed_property_query, window_named_property_getter,
|
||||
window_named_property_query,
|
||||
};
|
||||
|
||||
@@ -64,6 +64,17 @@ pub(in crate::context_bootstrap) fn window_indexed_property_getter<'s>(
|
||||
v8::Intercepted::kYes
|
||||
}
|
||||
|
||||
pub(in crate::context_bootstrap) fn window_indexed_property_setter(
|
||||
_scope: &mut v8::PinScope<'_, '_>,
|
||||
_index: u32,
|
||||
_value: v8::Local<'_, v8::Value>,
|
||||
_args: v8::PropertyCallbackArguments<'_>,
|
||||
mut rv: v8::ReturnValue<'_, v8::Boolean>,
|
||||
) -> v8::Intercepted {
|
||||
rv.set_bool(false);
|
||||
v8::Intercepted::kYes
|
||||
}
|
||||
|
||||
pub(in crate::context_bootstrap) fn window_indexed_property_query<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
index: u32,
|
||||
@@ -77,6 +88,17 @@ pub(in crate::context_bootstrap) fn window_indexed_property_query<'s>(
|
||||
v8::Intercepted::kYes
|
||||
}
|
||||
|
||||
pub(in crate::context_bootstrap) fn window_indexed_property_definer(
|
||||
_scope: &mut v8::PinScope<'_, '_>,
|
||||
_index: u32,
|
||||
_descriptor: &v8::PropertyDescriptor,
|
||||
_args: v8::PropertyCallbackArguments<'_>,
|
||||
mut rv: v8::ReturnValue<'_, v8::Boolean>,
|
||||
) -> v8::Intercepted {
|
||||
rv.set_bool(false);
|
||||
v8::Intercepted::kYes
|
||||
}
|
||||
|
||||
pub(in crate::context_bootstrap) fn window_indexed_property_deleter<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
index: u32,
|
||||
|
||||
@@ -372,9 +372,11 @@ pub(crate) fn install_window_own_template_bindings<'s>(
|
||||
window_template.set_indexed_property_handler(
|
||||
v8::IndexedPropertyHandlerConfiguration::new()
|
||||
.getter(window_indexed_property_getter)
|
||||
.setter(window_indexed_property_setter)
|
||||
.query(window_indexed_property_query)
|
||||
.deleter(window_indexed_property_deleter)
|
||||
.enumerator(window_indexed_property_enumerator)
|
||||
.definer(window_indexed_property_definer)
|
||||
.descriptor(window_indexed_property_descriptor),
|
||||
);
|
||||
// Window is a [Global] WebIDL interface. Blink installs its members on the
|
||||
|
||||
@@ -15241,6 +15241,72 @@ fn main_window_indexed_child_deletion_is_live_and_not_cached() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn main_window_indexed_set_and_define_reject_every_array_index() {
|
||||
let mut vm = new_storage_test_vm("https://window-indexed-write.test/");
|
||||
|
||||
let result = vm
|
||||
.eval(
|
||||
r#"
|
||||
(() => {
|
||||
const frame = document.createElement('iframe');
|
||||
(document.body || document.documentElement || document).appendChild(frame);
|
||||
const child = frame.contentWindow;
|
||||
const strictSetThrows = index => {
|
||||
'use strict';
|
||||
try {
|
||||
window[index] = 'strict';
|
||||
return false;
|
||||
} catch (error) {
|
||||
return error instanceof TypeError;
|
||||
}
|
||||
};
|
||||
const defineThrows = (index, descriptor) => {
|
||||
try {
|
||||
Object.defineProperty(window, index, descriptor);
|
||||
return false;
|
||||
} catch (error) {
|
||||
return error instanceof TypeError;
|
||||
}
|
||||
};
|
||||
|
||||
window[0] = 'sloppy';
|
||||
window[1] = 'sloppy';
|
||||
window[4294967294] = 'sloppy';
|
||||
const result = {
|
||||
existingChildPreserved: window[0] === child,
|
||||
existingStrictSetThrows: strictSetThrows(0),
|
||||
existingReflectSet: Reflect.set(window, 0, 'reflect'),
|
||||
existingReflectDefine: Reflect.defineProperty(window, 0, { value: 'reflect' }),
|
||||
existingDefineThrows: defineThrows(0, { get: () => 'getter' }),
|
||||
missingRemainsAbsent: window[1] === undefined,
|
||||
missingStrictSetThrows: strictSetThrows(1),
|
||||
missingReflectSet: Reflect.set(window, 1, 'reflect'),
|
||||
missingReflectDefine: Reflect.defineProperty(window, 1, { value: 'reflect' }),
|
||||
missingDefineThrows: defineThrows(1, { value: 'defined' }),
|
||||
maxIndexRemainsAbsent: window[4294967294] === undefined,
|
||||
maxIndexStrictSetThrows: strictSetThrows(4294967294),
|
||||
maxIndexReflectSet: Reflect.set(window, 4294967294, 'reflect'),
|
||||
maxIndexReflectDefine: Reflect.defineProperty(window, 4294967294, { value: 'reflect' })
|
||||
};
|
||||
window[4294967295] = 1;
|
||||
result.nonIndexSet = window[4294967295];
|
||||
result.nonIndexReflectSet = Reflect.set(window, 4294967295, 2);
|
||||
result.nonIndexAfterReflectSet = window[4294967295];
|
||||
result.nonIndexReflectDefine = Reflect.defineProperty(window, 4294967295, { value: 3 });
|
||||
result.nonIndexAfterDefine = window[4294967295];
|
||||
return JSON.stringify(result);
|
||||
})()
|
||||
"#,
|
||||
)
|
||||
.expect("Window indexed write and define probe should evaluate");
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
r#"{"existingChildPreserved":true,"existingStrictSetThrows":true,"existingReflectSet":false,"existingReflectDefine":false,"existingDefineThrows":true,"missingRemainsAbsent":true,"missingStrictSetThrows":true,"missingReflectSet":false,"missingReflectDefine":false,"missingDefineThrows":true,"maxIndexRemainsAbsent":true,"maxIndexStrictSetThrows":true,"maxIndexReflectSet":false,"maxIndexReflectDefine":false,"nonIndexSet":1,"nonIndexReflectSet":true,"nonIndexAfterReflectSet":2,"nonIndexReflectDefine":true,"nonIndexAfterDefine":3}"#
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn main_window_indexed_child_descriptor_matches_window_semantics() {
|
||||
let mut vm = new_storage_test_vm("https://window-indexed-descriptor.test/");
|
||||
|
||||
Reference in New Issue
Block a user