From ca54691ecf9ca2da62bd3acc39ab6449a0e5cfc3 Mon Sep 17 00:00:00 2001 From: Kenneth Myhra Date: Sun, 10 Mar 2024 20:37:41 +0100 Subject: [PATCH] LibWeb: Add structured_deserialize_internal() structured_deserialize_internal() is added to support sub deserialization from serializable interfaces serialization steps which needs the ability to pass onto the current position in the deserialized data. --- .../LibWeb/HTML/StructuredSerialize.cpp | 25 ++++++++++++++----- .../LibWeb/HTML/StructuredSerialize.h | 6 +++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index e6c80c438f9..750bad8b105 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -663,14 +663,17 @@ template WebIDL::ExceptionOr serialize_viewed_array_buffer(JS::VM& vm, Vec class Deserializer { public: - Deserializer(JS::VM& vm, JS::Realm& target_realm, ReadonlySpan serialized, DeserializationMemory& memory) + Deserializer(JS::VM& vm, JS::Realm& target_realm, ReadonlySpan serialized, DeserializationMemory& memory, Optional position = {}) : m_vm(vm) , m_serialized(serialized) , m_memory(memory) + , m_position(position.value_or(0)) { VERIFY(vm.current_realm() == &target_realm); } + size_t position() const { return m_position; } + // https://html.spec.whatwg.org/multipage/structured-data.html#structureddeserialize WebIDL::ExceptionOr deserialize() { @@ -960,8 +963,8 @@ public: private: JS::VM& m_vm; ReadonlySpan m_serialized; - size_t m_position { 0 }; JS::MarkedVector m_memory; // Index -> JS value + size_t m_position { 0 }; static WebIDL::ExceptionOr> create_serialized_type(StringView interface_name, JS::Realm& realm) { @@ -1288,12 +1291,22 @@ WebIDL::ExceptionOr structured_deserialize(JS::VM& vm, SerializationR auto& target_settings = Bindings::host_defined_environment_settings_object(target_realm); target_settings.prepare_to_run_script(); - Deserializer deserializer(vm, target_realm, serialized.span(), *memory); - - auto result = deserializer.deserialize(); + auto result = TRY(structured_deserialize_internal(vm, serialized.span(), target_realm, *memory)); target_settings.clean_up_after_running_script(); - return result; + VERIFY(result.value.has_value()); + return *result.value; +} + +WebIDL::ExceptionOr structured_deserialize_internal(JS::VM& vm, ReadonlySpan const& serialized, JS::Realm& target_realm, DeserializationMemory& memory, Optional position) +{ + Deserializer deserializer(vm, target_realm, serialized, memory, move(position)); + auto value = TRY(deserializer.deserialize()); + auto deserialized_record = DeserializedRecord { + .value = value, + .position = deserializer.position(), + }; + return deserialized_record; } } diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h index 96894650dee..c68476a6f42 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h @@ -41,6 +41,11 @@ struct DeserializedTransferRecord { Vector> transferred_values; }; +struct DeserializedRecord { + Optional value; + size_t position; +}; + enum class TransferType : u8 { MessagePort, }; @@ -50,6 +55,7 @@ WebIDL::ExceptionOr structured_serialize_for_storage(JS::VM WebIDL::ExceptionOr structured_serialize_internal(JS::VM& vm, JS::Value, bool for_storage, SerializationMemory&); WebIDL::ExceptionOr structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional); +WebIDL::ExceptionOr structured_deserialize_internal(JS::VM& vm, ReadonlySpan const& serialized, JS::Realm& target_realm, DeserializationMemory& memory, Optional position = {}); void serialize_boolean_primitive(SerializationRecord& serialized, JS::Value& value); void serialize_number_primitive(SerializationRecord& serialized, JS::Value& value);