fix(inspect): handle circular refs and non-object props in JSX formatter#30362
fix(inspect): handle circular refs and non-object props in JSX formatter#30362robobun wants to merge 1 commit into
Conversation
The JSX/React element formatter in Bun.inspect/console.log did not participate in circular reference detection, so inspecting an element whose props (or children) referenced the element itself would recurse until the stack overflowed and crash. Add .JSX to canHaveCircularReferences so it gets the same visited-map and stack-check protection as Object/Array/etc, and guard against non-object props values instead of force-unwrapping.
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
Comment |
|
Updated 1:15 AM PT - May 7th, 2026
❌ @robobun, your commit 37e2701 has 1 failures in
🧪 To try this PR locally: bunx bun-pr 30362That installs a local version of the PR into your bun-30362 --bun |
|
This PR may be a duplicate of:
🤖 Generated with Claude Code |
|
Duplicate of #29709 (which also covers |
There was a problem hiding this comment.
LGTM — minimal, well-tested fix for a fuzzer-found crash.
Extended reasoning...
Overview
This PR fixes two crashes in Bun.inspect()'s JSX formatter (src/jsc/ConsoleObject.zig): (1) adds .JSX to canHaveCircularReferences() so the existing visited-map and StackCheck guard at the top of printAs now protects JSX elements from infinite recursion through circular props/children, and (2) replaces the props.getObject().? force-unwrap with a safe if (props.getObject()) |props_obj| so a primitive props value no longer panics. Four regression tests are added to test/js/bun/util/inspect.test.js.
Security risks
None. This is purely output-formatting code for Bun.inspect/console.log. The change strictly hardens against malformed input (circular refs, non-object props) found by Fuzzilli; no auth, crypto, or permission paths are touched.
Level of scrutiny
Low. The first change is a one-token addition to an existing switch arm, reusing the exact circular-reference machinery already applied to .Object, .Array, .Map, etc. — the guard wraps the whole switch (comptime Format) block, so .JSX slots in with no behavioral surprises beyond printing [Circular] instead of overflowing the stack. The second change replaces an incorrect SAFETY: assumption (props are not guaranteed to be objects since $$typeof detection works on any user object) with a null-safe optional unwrap; non-object props now render as <div />, which is reasonable.
Other factors
The new tests cover all four scenarios (circular props object, circular prop value, circular children, primitive props) and the description confirms all 76 inspect tests pass while the new tests crash the unpatched binary. No CODEOWNERS apply to these paths and the bug-hunting system found no issues.
What does this PR do?
Bun.inspect()/console.log()crashed with a stack overflow when formatting a React element whoseprops(or a prop value, orchildren) referenced the element itself:The
.JSXtag was missing fromcanHaveCircularReferences(), so the visited-map check and theStackCheckguard that protect other recursive formatters (.Object,.Array,.Map, …) never ran for JSX elements, allowing unbounded recursion intoprops/children.Also removes the
props.getObject().?force-unwrap — since$$typeofdetection works on any object,propsis user-controlled and can be a primitive, which previously panicked with "attempt to use null value".Now prints
[Circular]like other circular structures:Found by Fuzzilli. Fingerprint:
ae1fb4ec8882b8cfHow did you verify your code works?
Added tests in
test/js/bun/util/inspect.test.jscovering circularprops, circular prop values, circularchildren, and non-objectprops. All 76 inspect tests pass withbun bd test; the new tests crash the system bun.