fix(json): serialize TypedArray in JSON.stringify instead of SIGSEGV (#5111)#5114
Conversation
…5111) JSON.stringify of a TypedArray (a map/subarray/slice/filter result, or even a plain `new Int32Array([...])`) segfaulted: the stringify value dispatchers had no TypedArray arm, so a TypedArrayHeader-backed view reached the gc_obj_type tag read — but small typed arrays are plain-alloc'd with no GcHeader, so the read 8 bytes before the header pulled in unrelated allocator metadata and dispatched to a random arm. Detect a registered typed array via lookup_typed_array_kind BEFORE gc_obj_type (the same pre-check already used for Buffer/Uint8Array, which also lack a GcHeader) and serialize it in Node's index shape {"0":v,...}. New helpers stringify_typed_array / stringify_typed_array_pretty are wired into every buffer-dispatch site (stringify_value, stringify_value_depth, the nested array-element path, and the replacer/pretty walks). Elements funnel through write_number, so NaN/Infinity render as null and BigInt views throw Node's "Do not know how to serialize a BigInt" TypeError. Output matches node --experimental-strip-types byte-for-byte. https://claude.ai/code/session_014AH46fwU7BaRRxkMc5Zcq2
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (6)
📝 WalkthroughWalkthroughAdds ChangesTypedArray JSON.stringify SIGSEGV Fix
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Fixes #5111.
Problem
JSON.stringifyof a TypedArray segfaulted — themap/subarrayresults from the issue, but alsoslice/filterresults and even a plainJSON.stringify(new Int32Array([1,2,3])).Root cause
The stringify value dispatchers had no TypedArray arm. A
TypedArrayHeader-backed view fell through to thegc_obj_typetag read — but small typed arrays are plain-alloc'd with noGcHeader, so reading 8 bytes before the header pulled in unrelated allocator metadata and dispatched to a random arm (the SIGSEGV). TheArray.from/spread "garbage" symptom was the same mis-dispatch reading wrong element kinds/offsets.This is exactly the hazard already handled for
Buffer/Uint8Array(which also have noGcHeader): they're detected via a registry pre-check beforegc_obj_type.Fix
Detect a registered typed array via
lookup_typed_array_kindbeforegc_obj_type, and serialize it in Node's index shape{"0":v,…}. Two new helpers injson/stringify.rs:stringify_typed_array— compact formstringify_typed_array_pretty— thespace-indented formwired into every buffer-dispatch site:
stringify_value,stringify_value_depth, the nested array-element path, and the replacer/pretty walks injson/replacer.rs. Each element funnels throughwrite_number, soNaN/±Infinityrender asnulland aBigInt64/BigUint64element throws Node'sTypeError: Do not know how to serialize a BigInt.Verification
Output is byte-for-byte identical to
node --experimental-strip-typesfor the typed array as a root value, an object field, and an array element, in both compact and 3-arg pretty forms — includingmap/subarray/slice/filterresults,NaN→null, empty array →{}, and the BigInt throw.Array.from/spread of amapresult now read correctly too.stringify_typed_array_emits_node_index_shapeperry-runtimeJSON test suite: 42 passed, 0 failedhttps://claude.ai/code/session_014AH46fwU7BaRRxkMc5Zcq2
Generated by Claude Code
Summary by CodeRabbit
Release Notes