mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:07:46 +00:00
LibWeb: Use `Vector<Handle<Object>>
` in transfer variants of serialize
Also trap the invalid object index inserted for transferred values in deserialization. In the future we should avoid inserting that placeholder value in the data stream at all.
This commit is contained in:
parent
73697058b0
commit
84ac6a454f
2 changed files with 17 additions and 12 deletions
|
@ -578,6 +578,10 @@ public:
|
||||||
// 2. If memory[serialized] exists, then return memory[serialized].
|
// 2. If memory[serialized] exists, then return memory[serialized].
|
||||||
if (tag == ValueTag::ObjectReference) {
|
if (tag == ValueTag::ObjectReference) {
|
||||||
auto index = m_serialized[m_position++];
|
auto index = m_serialized[m_position++];
|
||||||
|
// FIXME: For transferred items, find a way to avoid putting placeholders in the serialized data
|
||||||
|
if (index == NumericLimits<u32>::max()) {
|
||||||
|
return JS::js_null();
|
||||||
|
}
|
||||||
return m_memory[index];
|
return m_memory[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,7 +925,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializewithtransfer
|
// https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializewithtransfer
|
||||||
WebIDL::ExceptionOr<SerializedTransferRecord> structured_serialize_with_transfer(JS::VM& vm, JS::Value value, JS::MarkedVector<JS::Value> transfer_list)
|
WebIDL::ExceptionOr<SerializedTransferRecord> structured_serialize_with_transfer(JS::VM& vm, JS::Value value, Vector<JS::Handle<JS::Object>> const& transfer_list)
|
||||||
{
|
{
|
||||||
// 1. Let memory be an empty map.
|
// 1. Let memory be an empty map.
|
||||||
SerializationMemory memory = {};
|
SerializationMemory memory = {};
|
||||||
|
@ -931,19 +935,20 @@ WebIDL::ExceptionOr<SerializedTransferRecord> structured_serialize_with_transfer
|
||||||
|
|
||||||
// 1. If transferable has neither an [[ArrayBufferData]] internal slot nor a [[Detached]] internal slot, then throw a "DataCloneError" DOMException.
|
// 1. If transferable has neither an [[ArrayBufferData]] internal slot nor a [[Detached]] internal slot, then throw a "DataCloneError" DOMException.
|
||||||
// FIXME: Handle transferring ArrayBufferData objects
|
// FIXME: Handle transferring ArrayBufferData objects
|
||||||
if (!transferable.is_object() || !is<Bindings::Transferable>(transferable.as_object())) {
|
if (!is<Bindings::Transferable>(*transferable)) {
|
||||||
return WebIDL::DataCloneError::create(*vm.current_realm(), "Cannot transfer type"_fly_string);
|
return WebIDL::DataCloneError::create(*vm.current_realm(), "Cannot transfer type"_fly_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 2. If transferable has an [[ArrayBufferData]] internal slot and IsSharedArrayBuffer(transferable) is true, then throw a "DataCloneError" DOMException.
|
// FIXME: 2. If transferable has an [[ArrayBufferData]] internal slot and IsSharedArrayBuffer(transferable) is true, then throw a "DataCloneError" DOMException.
|
||||||
|
|
||||||
// 3. If memory[transferable] exists, then throw a "DataCloneError" DOMException.
|
// 3. If memory[transferable] exists, then throw a "DataCloneError" DOMException.
|
||||||
if (memory.contains(transferable)) {
|
auto transferable_value = JS::Value(transferable.ptr());
|
||||||
|
if (memory.contains(transferable_value)) {
|
||||||
return WebIDL::DataCloneError::create(*vm.current_realm(), "Cannot transfer value twice"_fly_string);
|
return WebIDL::DataCloneError::create(*vm.current_realm(), "Cannot transfer value twice"_fly_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Set memory[transferable] to { [[Type]]: an uninitialized value }.
|
// 4. Set memory[transferable] to { [[Type]]: an uninitialized value }.
|
||||||
memory.set(JS::make_handle(transferable), NumericLimits<u32>::max());
|
memory.set(JS::make_handle(transferable_value), NumericLimits<u32>::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Let serialized be ? StructuredSerializeInternal(value, false, memory).
|
// 3. Let serialized be ? StructuredSerializeInternal(value, false, memory).
|
||||||
|
@ -958,8 +963,8 @@ WebIDL::ExceptionOr<SerializedTransferRecord> structured_serialize_with_transfer
|
||||||
// 1. FIXME: If transferable has an [[ArrayBufferData]] internal slot and IsDetachedBuffer(transferable) is true, then throw a "DataCloneError" DOMException.
|
// 1. FIXME: If transferable has an [[ArrayBufferData]] internal slot and IsDetachedBuffer(transferable) is true, then throw a "DataCloneError" DOMException.
|
||||||
|
|
||||||
// 2. If transferable has a [[Detached]] internal slot and transferable.[[Detached]] is true, then throw a "DataCloneError" DOMException.
|
// 2. If transferable has a [[Detached]] internal slot and transferable.[[Detached]] is true, then throw a "DataCloneError" DOMException.
|
||||||
if (transferable.is_object() && is<Bindings::Transferable>(transferable.as_object())) {
|
if (is<Bindings::Transferable>(*transferable)) {
|
||||||
auto& transferable_object = dynamic_cast<Bindings::Transferable&>(transferable.as_object());
|
auto& transferable_object = dynamic_cast<Bindings::Transferable&>(*transferable);
|
||||||
if (transferable_object.is_detached()) {
|
if (transferable_object.is_detached()) {
|
||||||
return WebIDL::DataCloneError::create(*vm.current_realm(), "Value already transferred"_fly_string);
|
return WebIDL::DataCloneError::create(*vm.current_realm(), "Value already transferred"_fly_string);
|
||||||
}
|
}
|
||||||
|
@ -976,8 +981,8 @@ WebIDL::ExceptionOr<SerializedTransferRecord> structured_serialize_with_transfer
|
||||||
// 5. Otherwise:
|
// 5. Otherwise:
|
||||||
else {
|
else {
|
||||||
// 1. Assert: transferable is a platform object that is a transferable object.
|
// 1. Assert: transferable is a platform object that is a transferable object.
|
||||||
auto& transferable_object = dynamic_cast<Bindings::Transferable&>(transferable.as_object());
|
auto& transferable_object = dynamic_cast<Bindings::Transferable&>(*transferable);
|
||||||
VERIFY(is<Bindings::PlatformObject>(transferable.as_object()));
|
VERIFY(is<Bindings::PlatformObject>(*transferable));
|
||||||
|
|
||||||
// 2. Let interfaceName be the identifier of the primary interface of transferable.
|
// 2. Let interfaceName be the identifier of the primary interface of transferable.
|
||||||
auto interface_name = transferable_object.primary_interface();
|
auto interface_name = transferable_object.primary_interface();
|
||||||
|
@ -1035,7 +1040,7 @@ WebIDL::ExceptionOr<DeserializedTransferRecord> structured_deserialize_with_tran
|
||||||
auto memory = DeserializationMemory(vm.heap());
|
auto memory = DeserializationMemory(vm.heap());
|
||||||
|
|
||||||
// 2. Let transferredValues be a new empty List.
|
// 2. Let transferredValues be a new empty List.
|
||||||
auto transferred_values = JS::MarkedVector<JS::Value>(vm.heap());
|
Vector<JS::Handle<JS::Object>> transferred_values;
|
||||||
|
|
||||||
// 3. For each transferDataHolder of serializeWithTransferResult.[[TransferDataHolders]]:
|
// 3. For each transferDataHolder of serializeWithTransferResult.[[TransferDataHolders]]:
|
||||||
for (auto& transfer_data_holder : serialize_with_transfer_result.transfer_data_holders) {
|
for (auto& transfer_data_holder : serialize_with_transfer_result.transfer_data_holders) {
|
||||||
|
@ -1078,7 +1083,7 @@ WebIDL::ExceptionOr<DeserializedTransferRecord> structured_deserialize_with_tran
|
||||||
memory.append(value);
|
memory.append(value);
|
||||||
|
|
||||||
// 6. Append value to transferredValues.
|
// 6. Append value to transferredValues.
|
||||||
transferred_values.append(value);
|
transferred_values.append(JS::make_handle(value.as_object()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Let deserialized be ? StructuredDeserialize(serializeWithTransferResult.[[Serialized]], targetRealm, memory).
|
// 4. Let deserialized be ? StructuredDeserialize(serializeWithTransferResult.[[Serialized]], targetRealm, memory).
|
||||||
|
|
|
@ -37,7 +37,7 @@ struct SerializedTransferRecord {
|
||||||
|
|
||||||
struct DeserializedTransferRecord {
|
struct DeserializedTransferRecord {
|
||||||
JS::Value deserialized;
|
JS::Value deserialized;
|
||||||
JS::MarkedVector<JS::Value> transferred_values;
|
Vector<JS::Handle<JS::Object>> transferred_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class TransferType : u8 {
|
enum class TransferType : u8 {
|
||||||
|
@ -50,7 +50,7 @@ WebIDL::ExceptionOr<SerializationRecord> structured_serialize_internal(JS::VM& v
|
||||||
|
|
||||||
WebIDL::ExceptionOr<JS::Value> structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional<DeserializationMemory>);
|
WebIDL::ExceptionOr<JS::Value> structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional<DeserializationMemory>);
|
||||||
|
|
||||||
WebIDL::ExceptionOr<SerializedTransferRecord> structured_serialize_with_transfer(JS::VM& vm, JS::Value value, JS::MarkedVector<JS::Value> transfer_list);
|
WebIDL::ExceptionOr<SerializedTransferRecord> structured_serialize_with_transfer(JS::VM& vm, JS::Value value, Vector<JS::Handle<JS::Object>> const& transfer_list);
|
||||||
WebIDL::ExceptionOr<DeserializedTransferRecord> structured_deserialize_with_transfer(JS::VM& vm, SerializedTransferRecord const&);
|
WebIDL::ExceptionOr<DeserializedTransferRecord> structured_deserialize_with_transfer(JS::VM& vm, SerializedTransferRecord const&);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue