From 267074cd8107a4f2073af0eef12e83f3eaf76c49 Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Mon, 11 Sep 2023 16:32:13 -0600 Subject: [PATCH] LibWeb: Add {de}serialization steps for RegExpObjects We skip serializing any of the internal state of the Regex object, because that state is all computable from the input pattern and flags. If it turns out that this is really, really slow, we can add some optimizations to serialize more of the regex parse result. --- .../StructuredClone-object-primitives.txt | 1 + .../StructuredClone-object-primitives.html | 1 + .../LibWeb/HTML/StructuredSerialize.cpp | 24 ++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt b/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt index d3eebbfa88..3955abadde 100644 --- a/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt +++ b/Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt @@ -5,4 +5,5 @@ false This is a String object 9007199254740991 1692748800000 +/abc/gimsuy 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 512ef6c7e5..0ba2a843e5 100644 --- a/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html +++ b/Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html @@ -8,6 +8,7 @@ println(structuredClone(new String("This is a String object"))); println(structuredClone(BigInt("0x1fffffffffffff"))); println(structuredClone(Date.UTC(2023, 7, 23))); + println(structuredClone(/abc/gimsuy)); try { structuredClone(Symbol("foo")); diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index 61f3ece718..96bb3b60e0 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,8 @@ enum ValueTag { DateObject, + RegExpObject, + // TODO: Define many more types // This tag or higher are understood to be errors @@ -171,7 +174,20 @@ public: m_serialized.append(bit_cast(&date_value), 2); } - // 12 - 24: FIXME: Serialize other data types + // 12. Otherwise, if value has a [[RegExpMatcher]] internal slot, then set serialized to + // { [[Type]]: "RegExp", [[RegExpMatcher]]: value.[[RegExpMatcher]], [[OriginalSource]]: value.[[OriginalSource]], + // [[OriginalFlags]]: value.[[OriginalFlags]] }. + else if (value.is_object() && is(value.as_object())) { + m_serialized.append(ValueTag::RegExpObject); + auto& regexp_object = static_cast(value.as_object()); + // Note: A Regex object is perfectly happy to be reconstructed with just the source+flags + // In the future, we could optimize the work being done on the deserialize step by serializing + // more of the internal state (the [[RegExpMatcher]] internal slot) + TRY(serialize_string(m_serialized, TRY_OR_THROW_OOM(m_vm, String::from_deprecated_string(regexp_object.pattern())))); + TRY(serialize_string(m_serialized, TRY_OR_THROW_OOM(m_vm, String::from_deprecated_string(regexp_object.flags())))); + } + + // 13 - 24: FIXME: Serialize other data types else { return throw_completion(WebIDL::DataCloneError::create(*m_vm.current_realm(), "Unsupported type"_fly_string)); } @@ -301,6 +317,12 @@ public: m_memory.append(JS::Date::create(*realm, value)); break; } + case ValueTag::RegExpObject: { + auto pattern = TRY(deserialize_string_primitive(m_vm, m_vector, position)); + auto flags = TRY(deserialize_string_primitive(m_vm, m_vector, position)); + m_memory.append(TRY(JS::regexp_create(m_vm, move(pattern), move(flags)))); + break; + } default: m_error = "Unsupported type"_fly_string; break;