LibWeb: Use enum for serialization and reimplement interface exposure

Our currently implementation of structured serialization has a design
flaw, where if the serialized/transferred type was not used in the
destination realm, it would not be seen as exposed and thus we would
not re-create the type on the other side.

This is very common, for example, transferring a MessagePort to a just
inserted iframe, or the just inserted iframe transferring a MessagePort
to it's parent. This is what Google reCAPTCHA does.

This flaw occurred due to relying on lazily populated HashMaps of
constructors, namespaces and interfaces. This commit changes it so that
per-type "is exposed" implementations are generated.

Since it no longer relies on interface name strings, this commit
changes serializable types to indicate their type with an enum,
in line with how transferrable types indicate their type.

This makes Google reCAPTCHA work on https://www.google.com/recaptcha/api2/demo
It currently doesn't work on non-Google origins due to a separate
same-origin policy bug.
This commit is contained in:
Luke Wilde 2025-07-14 17:15:09 +01:00 committed by Tim Flynn
commit d08d6b08d3
Notes: github-actions[bot] 2025-07-15 13:21:14 +00:00
25 changed files with 356 additions and 130 deletions

View file

@ -0,0 +1,20 @@
iframe received an object: Error
iframe received an object: [object DOMRectReadOnly]
iframe received an object: [object DOMRect]
iframe received an object: [object Blob]
iframe received an object: [object ImageBitmap]
iframe received an object: [object CryptoKey]
iframe received an object: [object File]
iframe received an object: [object FileList]
iframe received an object: matrix(1, 2, 3, 4, 5, 6)
iframe received an object: matrix(6, 5, 4, 3, 2, 1)
iframe received an object: [object DOMPointReadOnly]
iframe received an object: [object DOMPoint]
iframe received an object: [object DOMQuad]
iframe received an object: [object ImageData]
iframe received an object: [object MessagePort]
iframe received an object: [object ArrayBuffer]
iframe received an object: [object ArrayBuffer]
iframe received an object: [object ReadableStream]
iframe received an object: [object WritableStream]
iframe received an object: [object TransformStream]

View file

@ -1,52 +1,46 @@
Summary
Harness status: OK
Rerun
Found 41 tests
36 Pass
5 Fail
Details
Result Test Name MessagePass Primitive string is cloned
Pass Primitive integer is cloned
Pass Primitive floating point is cloned
Pass Primitive floating point (negative) is cloned
Pass Primitive number (hex) is cloned
Pass Primitive number (scientific) is cloned
Pass Primitive boolean is cloned
Pass Instance of Boolean is cloned
Pass Instance of Number is cloned
Pass Instance of String is cloned
Pass Instance of Date is cloned
Pass Instance of RegExp is cloned
Pass Value 'null' is cloned
Pass Value 'undefined' is cloned
Pass Object properties are cloned
Pass Prototype chains are not walked.
Pass Property descriptors of Objects are not cloned
Pass Cycles are preserved in Objects
Fail Identity of duplicates is preserved
Pass Property order is preserved
Pass Enumerable properties of Arrays are cloned
Pass Property descriptors of Arrays are not cloned
Pass Cycles are preserved in Arrays
Fail ImageData object can be cloned Cannot serialize platform objects
Fail ImageData expandos are not cloned Cannot serialize platform objects
Pass Window objects cannot be cloned
Pass Document objects cannot be cloned
Pass Empty Error objects can be cloned
Pass Error objects can be cloned
Pass EvalError objects can be cloned
Pass RangeError objects can be cloned
Pass ReferenceError objects can be cloned
Pass SyntaxError objects can be cloned
Pass TypeError objects can be cloned
Pass URIError objects can be cloned
Pass URIError objects from other realms are treated as URIError
Pass Cloning a modified Error
Pass Error.message: getter is ignored when cloning
Pass Error.message: undefined property is stringified
Fail DOMException objects can be cloned Cannot serialize platform objects
Fail DOMException objects created by the UA can be cloned Cannot serialize platform objects
41 Pass
Pass Primitive string is cloned
Pass Primitive integer is cloned
Pass Primitive floating point is cloned
Pass Primitive floating point (negative) is cloned
Pass Primitive number (hex) is cloned
Pass Primitive number (scientific) is cloned
Pass Primitive boolean is cloned
Pass Instance of Boolean is cloned
Pass Instance of Number is cloned
Pass Instance of String is cloned
Pass Instance of Date is cloned
Pass Instance of RegExp is cloned
Pass Value 'null' is cloned
Pass Value 'undefined' is cloned
Pass Object properties are cloned
Pass Prototype chains are not walked.
Pass Property descriptors of Objects are not cloned
Pass Cycles are preserved in Objects
Pass Identity of duplicates is preserved
Pass Property order is preserved
Pass Enumerable properties of Arrays are cloned
Pass Property descriptors of Arrays are not cloned
Pass Cycles are preserved in Arrays
Pass ImageData object can be cloned
Pass ImageData expandos are not cloned
Pass Window objects cannot be cloned
Pass Document objects cannot be cloned
Pass Empty Error objects can be cloned
Pass Error objects can be cloned
Pass EvalError objects can be cloned
Pass RangeError objects can be cloned
Pass ReferenceError objects can be cloned
Pass SyntaxError objects can be cloned
Pass TypeError objects can be cloned
Pass URIError objects can be cloned
Pass URIError objects from other realms are treated as URIError
Pass Cloning a modified Error
Pass Error.message: getter is ignored when cloning
Pass Error.message: undefined property is stringified
Pass DOMException objects can be cloned
Pass DOMException objects created by the UA can be cloned