mirror of
https://github.com/lexmount/moli.git
synced 2026-10-17 00:01:23 +00:00
fix(storage): build name arrays without inherited numeric setters
This commit is contained in:
@@ -3345,14 +3345,15 @@ fn strings_to_array<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
values: &[String],
|
||||
) -> v8::Local<'s, v8::Array> {
|
||||
let array = v8::Array::new(scope, values.len() as i32);
|
||||
for (index, value) in values.iter().enumerate() {
|
||||
let Some(value) = v8_string(scope, value) else {
|
||||
continue;
|
||||
};
|
||||
let _ = array.set_index(scope, index as u32, value.into());
|
||||
let mut elements = Vec::with_capacity(values.len());
|
||||
for value in values {
|
||||
elements.push(
|
||||
v8_string(scope, value)
|
||||
.expect("storage name should allocate")
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
array
|
||||
v8::Array::new_with_elements(scope, &elements)
|
||||
}
|
||||
|
||||
pub(in crate::context_bootstrap) fn navigator_ua_data_to_json_callback<'s>(
|
||||
|
||||
@@ -2167,6 +2167,7 @@ mod readable_algorithm_arrays;
|
||||
mod remote_playback_interface;
|
||||
mod rendering_update;
|
||||
mod script_terminal_completion;
|
||||
mod storage_dense_name_arrays;
|
||||
mod streams;
|
||||
mod svg_filter_interfaces;
|
||||
mod svg_number_validation;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
use super::*;
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn storage_name_arrays_ignore_numeric_prototype_properties() {
|
||||
let loader = static_http_loader(std::iter::empty::<String>());
|
||||
let mut vm = new_storage_page_task_executor_test_vm_with_loader(
|
||||
"https://storage-dense-name-arrays.test/",
|
||||
&loader,
|
||||
);
|
||||
assert_eq!(vm.eval(r#"(() => {
|
||||
const own=Object.getOwnPropertyDescriptor,define=Object.defineProperty;
|
||||
globalThis.__storageNameArrayFacts={complete:false,error:null};
|
||||
(async()=>{
|
||||
const apis=[navigator.storageBuckets,caches];
|
||||
for(let a=0;a<apis.length;a++) {
|
||||
const api=apis[a],name='dense-names-'+a,second=name+'-second';await api.open(name);await api.open(second);
|
||||
const expected=await api.keys();if(expected.length<2)throw Error('fixture needs both indices');
|
||||
for(const parent of [Array.prototype,Object.prototype])for(const index of ['0','1'])for(const kind of ['setter','throwing','getter','readonly']) {
|
||||
const old=own(parent,index);let calls=0,result;
|
||||
const descriptor=kind==='readonly'?{configurable:true,value:99,writable:false}:kind==='getter'?{configurable:true,get(){calls++;throw 42;}}:{configurable:true,set(){calls++;if(kind==='throwing')throw 43;}};
|
||||
define(parent,index,descriptor);
|
||||
try{result=await api.keys();}finally{if(old)define(parent,index,old);else delete parent[index];}
|
||||
if(calls||!Array.isArray(result)||Object.isFrozen(result)||JSON.stringify(result)!==JSON.stringify(expected))throw Error('dense names');
|
||||
for(let i=0;i<result.length;i++){const d=own(result,String(i));if(!d||!d.writable||!d.configurable||!d.enumerable||!('value' in d))throw Error('own item');}
|
||||
}
|
||||
await api.delete(name);await api.delete(second);
|
||||
}
|
||||
})().catch(error=>{__storageNameArrayFacts.error=String(error);}).finally(()=>{__storageNameArrayFacts.complete=true;});
|
||||
return 'ok';
|
||||
})()"#).expect("native regression"), "ok");
|
||||
advance_page_task_executor_until_eval_equals(
|
||||
&mut vm,
|
||||
&loader,
|
||||
"String(__storageNameArrayFacts.complete)",
|
||||
"true",
|
||||
"dense-storage-names",
|
||||
)
|
||||
.await;
|
||||
assert_eq!(
|
||||
vm.eval("String(__storageNameArrayFacts.error)").unwrap(),
|
||||
"null"
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user