Parent: #1
Problem
structured_clone.serialize() and deserialize() recurse directly through object/wrapper/view graphs with no explicit depth budget. A deeply nested JavaScript value or malformed byte stream can exhaust the host stack instead of producing a catchable clone failure.
The wire format also stores graph IDs, string lengths, collection counts, array element counts, and view offsets/lengths in fixed-width integers. Several serializer increments/casts and deserializer u64 -> usize casts currently rely on values fitting; oversized source state or hostile bytes can trap, wrap, or drive disproportionate work rather than fail closed.
Goal
Give structured clone an explicit, shared complexity contract for serialization, structural preflight, cleanup parsing, and deserialization. Reject excessive nesting and unrepresentable/impossible counts before recursion, allocation, or loops become unsafe.
Acceptance criteria
- Serialization and deserialization enforce an explicit maximum nesting depth and return a catchable clone error instead of exhausting the native stack.
- Structural preflight and
releaseSerialized()use the same depth bound. - Serializer graph IDs, string lengths, property counts, collection counts, and array counts use checked conversion/increment.
- Deserializer
u64 -> usizeconversions fail closed on narrower targets. - Wire counts are rejected when they are impossible for the remaining payload before large loops or allocations.
- Focused tests cover depth-at-limit, depth-over-limit, oversized counts/lengths, and cleanup of retained SAB tokens in rejected deep/trailing payloads.
- Worker/structuredClone regression tests remain green and the security limits are documented.