diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index c390d3e76e..4cf45babc1 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -26,6 +26,8 @@ namespace Web::HTML { +static WebIDL::ExceptionOr structured_deserialize_impl(JS::VM& vm, ReadonlySpan serialized, JS::Realm& target_realm, SerializationMemory& memory); + // Binary format: // A list of adjacent shallow values, which may contain references to other // values (noted by their position in the list, one value following another). @@ -309,11 +311,13 @@ private: class Deserializer { public: - Deserializer(JS::VM& vm, JS::Realm& target_realm, SerializationRecord const& v) + Deserializer(JS::VM& vm, JS::Realm& target_realm, ReadonlySpan v, SerializationMemory& serialization_memory) : m_vm(vm) , m_vector(v) , m_memory(target_realm.heap()) + , m_serialization_memory(serialization_memory) { + VERIFY(vm.current_realm() == &target_realm); } WebIDL::ExceptionOr deserialize() @@ -417,11 +421,12 @@ public: private: JS::VM& m_vm; - SerializationRecord const& m_vector; + ReadonlySpan m_vector; JS::MarkedVector m_memory; // Index -> JS value Optional m_error; + SerializationMemory& m_serialization_memory; - static WebIDL::ExceptionOr deserialize_bytes(JS::VM& vm, Vector const& vector, u32& position) + static WebIDL::ExceptionOr deserialize_bytes(JS::VM& vm, ReadonlySpan vector, u32& position) { u32 size_bits[2]; size_bits[0] = vector[position++]; @@ -441,7 +446,13 @@ private: return bytes; } - static WebIDL::ExceptionOr> deserialize_string_primitive(JS::VM& vm, Vector const& vector, u32& position) + static WebIDL::ExceptionOr deserialize_string(JS::VM& vm, ReadonlySpan vector, u32& position) + { + auto bytes = TRY(deserialize_bytes(vm, vector, position)); + return TRY_OR_THROW_OOM(vm, String::from_utf8(StringView { bytes })); + } + + static WebIDL::ExceptionOr> deserialize_string_primitive(JS::VM& vm, ReadonlySpan vector, u32& position) { auto bytes = TRY(deserialize_bytes(vm, vector, position)); @@ -450,7 +461,7 @@ private: })); } - static WebIDL::ExceptionOr> deserialize_big_int_primitive(JS::VM& vm, Vector const& vector, u32& position) + static WebIDL::ExceptionOr> deserialize_big_int_primitive(JS::VM& vm, ReadonlySpan vector, u32& position) { auto string = TRY(deserialize_string_primitive(vm, vector, position)); auto string_view = TRY(Bindings::throw_dom_exception_if_needed(vm, [&string]() { @@ -464,36 +475,43 @@ private: WebIDL::ExceptionOr structured_serialize(JS::VM& vm, JS::Value value) { // 1. Return ? StructuredSerializeInternal(value, false). - return structured_serialize_internal(vm, value, false, {}); + SerializationMemory memory = {}; + return structured_serialize_internal(vm, value, false, memory); } // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeforstorage WebIDL::ExceptionOr structured_serialize_for_storage(JS::VM& vm, JS::Value value) { // 1. Return ? StructuredSerializeInternal(value, true). - return structured_serialize_internal(vm, value, true, {}); + SerializationMemory memory = {}; + return structured_serialize_internal(vm, value, true, memory); } // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal -WebIDL::ExceptionOr structured_serialize_internal(JS::VM& vm, JS::Value value, bool for_storage, Optional memory) +WebIDL::ExceptionOr structured_serialize_internal(JS::VM& vm, JS::Value value, bool for_storage, SerializationMemory& memory) { // 1. If memory was not supplied, let memory be an empty map. - if (!memory.has_value()) - memory = SerializationMemory {}; + // IMPLEMENTATION DEFINED: We move this requirement up to the callers to make recursion easier - Serializer serializer(vm, *memory, for_storage); + Serializer serializer(vm, memory, for_storage); return serializer.serialize(value); } +WebIDL::ExceptionOr structured_deserialize_impl(JS::VM& vm, ReadonlySpan serialized, JS::Realm& target_realm, SerializationMemory& memory) +{ + // FIXME: Do the spec steps + Deserializer deserializer(vm, target_realm, serialized, memory); + TRY(deserializer.deserialize()); + return deserializer.result(); +} + // https://html.spec.whatwg.org/multipage/structured-data.html#structureddeserialize WebIDL::ExceptionOr structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional memory) { - // FIXME: Do the spec steps - (void)memory; + if (!memory.has_value()) + memory = SerializationMemory {}; - Deserializer deserializer(vm, target_realm, serialized); - TRY(deserializer.deserialize()); - return deserializer.result(); + return structured_deserialize_impl(vm, serialized.span(), target_realm, *memory); } } diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h index fa111f2d50..f32cec69c9 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h @@ -29,7 +29,7 @@ using SerializationMemory = HashMap, SerializationRange>; WebIDL::ExceptionOr structured_serialize(JS::VM& vm, JS::Value); WebIDL::ExceptionOr structured_serialize_for_storage(JS::VM& vm, JS::Value); -WebIDL::ExceptionOr structured_serialize_internal(JS::VM& vm, JS::Value, bool for_storage, Optional); +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);