Parent: #473 Related: #493, #755
Problem
JSON.parse decoded an escaped leading-NUL object key and passed those raw bytes directly to engine property storage. NUL-led storage names are reserved for symbols/private/internal slots, so the parsed public property was hidden from ordinary lookup, own-key enumeration, and reviver traversal.
Scope
- Canonically encode decoded JSON object names before property insertion.
- Use the same canonical storage key for reviver source-record lookup, then decode exactly once at the callback boundary.
- Preserve duplicate-key replacement, integer-index ordering, proto data-property semantics, escaped/unescaped key equivalence, source context, OOM behavior, and property attributes.
No-workaround rules
- No NUL rejection, key filtering, alternate hidden namespace, reviver skip, or special-case lookup.
- The existing engine-wide public-string key encoding remains the sole authority.
Acceptance
- Escaped NUL keys are ordinary enumerable own string properties with exact lookup and Object.keys behavior.
- Reviver receives the decoded key and matching source metadata in specified property order.
- Duplicate, integer-like, wide, proto, and ordinary controls remain exact.
- Focused normal and TSan tests pass without leaks or races.
- Exact-parent JSON Test262 inventory has zero regressions.
Evidence
- JSON units: 14 passed, 0 failed, 0 leaked.
- Focused TSan: 1 passed, 0 failed, 0 leaked.
- Exact-parent Test262 test/built-ins/JSON: 165 to 165 passed; 0 to 0 failed.