From b3bd232a5e2f646d7eefdbed8806d2dfa3a28d98 Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Mon, 21 Aug 2023 17:39:44 -0600 Subject: [PATCH] LibWeb: Implement StructuredSerialize for BigIntObject and Symbol --- .../StructuredClone-object-primitives.txt | 2 ++ .../StructuredClone-object-primitives.html | 9 +++++++++ .../LibWeb/HTML/StructuredSerialize.cpp | 20 +++++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt b/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt index 2508f71767..d3eebbfa88 100644 --- a/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt +++ b/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt @@ -3,4 +3,6 @@ false 123 123.456 This is a String object +9007199254740991 1692748800000 +ERROR: DataCloneError: Cannot serialize Symbol \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html b/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html index df2d3d1bde..512ef6c7e5 100644 --- a/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html +++ b/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html @@ -6,6 +6,15 @@ println(structuredClone(new Number(123))); println(structuredClone(new Number(123.456))); println(structuredClone(new String("This is a String object"))); + println(structuredClone(BigInt("0x1fffffffffffff"))); println(structuredClone(Date.UTC(2023, 7, 23))); + + try { + structuredClone(Symbol("foo")); + println("FAILED") + } + catch(e) { + println("ERROR: " + e.name + ": " + e.message) + } }); diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index 592328580b..99db5aa510 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,8 @@ enum ValueTag { NumberObject, + BigIntObject, + StringObject, DateObject, @@ -122,7 +125,9 @@ public: if (return_primitive_type) return m_serialized; - // FIXME 5. If Type(value) is Symbol, then throw a "DataCloneError" DOMException. + // 5. If Type(value) is Symbol, then throw a "DataCloneError" DOMException. + if (value.is_symbol()) + return WebIDL::DataCloneError::create(*m_vm.current_realm(), "Cannot serialize Symbol"sv); // 6. Let serialized be an uninitialized value. // NOTE: We use the range of the soon-to-be-serialized value in our serialized data buffer @@ -144,7 +149,12 @@ public: m_serialized.append(bit_cast(&number), 2); } - // FIXME 9. Otherwise, if value has a [[BigIntData]] internal slot, then set serialized to { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }. + // 9. Otherwise, if value has a [[BigIntData]] internal slot, then set serialized to { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }. + else if (value.is_object() && is(value.as_object())) { + m_serialized.append(ValueTag::BigIntObject); + auto& bigint_object = static_cast(value.as_object()); + TRY(serialize_string(m_serialized, TRY_OR_THROW_OOM(m_vm, bigint_object.bigint().to_string()))); + } // 10. Otherwise, if value has a [[StringData]] internal slot, then set serialized to { [[Type]]: "String", [[StringData]]: value.[[StringData]] }. else if (value.is_object() && is(value.as_object())) { @@ -270,6 +280,12 @@ public: m_memory.append(JS::NumberObject::create(*realm, value)); break; } + case ValueTag::BigIntObject: { + auto* realm = m_vm.current_realm(); + auto big_int = TRY(deserialize_big_int_primitive(m_vm, m_vector, position)); + m_memory.append(JS::BigIntObject::create(*realm, big_int)); + break; + } case ValueTag::StringObject: { auto* realm = m_vm.current_realm(); auto string = TRY(deserialize_string_primitive(m_vm, m_vector, position));