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));