fix(bindings): prevent null cell crash in PropertyCallback handlers on exception#27307
fix(bindings): prevent null cell crash in PropertyCallback handlers on exception#27307
Conversation
…n exception
PropertyCallback handlers like constructBunShell return `{}` (empty
JSValue, encoded as 0x0) when an exception occurs. JSC's
reifyStaticProperty passes this value to putDirect, which calls
isGetterSetter() on it. The empty JSValue passes the isCell() check
(since 0x0 has no tag bits set) but yields a null cell pointer,
causing a null pointer dereference.
Return jsUndefined() instead of {} from PropertyCallback handlers that
can throw exceptions (constructBunShell, defaultBunSQLObject,
constructBunSQLObject). jsUndefined() has tag bits set so isCell()
returns false, avoiding the null dereference. The pending exception
still propagates normally.
|
No actionable comments were generated in the recent review. 🎉 WalkthroughChange error-path returns in Changes
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
|
Updated 9:05 PM PT - Feb 20th, 2026
✅ @claude, your commit 17f1a1b1672b27c052f796de8500f03d41f1f0c7 passed in 🧪 To try this PR locally: bunx bun-pr 27307That installs a local version of the PR into your bun-27307 --bun |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/js/bun/shell/shell-property-callback-crash.test.ts`:
- Line 37: Remove the negative assertion that checks stderr for "runtime error"
by deleting the expect(stderr).not.toContain("runtime error"); line in the test
(the assertion that references stderr and .not.toContain("runtime error")). Rely
solely on the existing exit code assertion (the exit code check/assertion in the
test) as the crash indicator, so no additional checks against stderr are
performed.
|
|
||
| const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); | ||
|
|
||
| expect(stderr).not.toContain("runtime error"); |
There was a problem hiding this comment.
Remove the negative assertion for "runtime error" in stderr.
As per coding guidelines, tests should never check for the absence of 'panic', 'uncaught exception', or similar strings in test output because these tests will never fail in CI if the fix regresses. The exit code check on line 38 is the reliable indicator of a crash. If the null pointer dereference occurs, the process will exit with a non-zero code.
Proposed fix
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
- expect(stderr).not.toContain("runtime error");
expect(exitCode).toBe(0);
});🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@test/js/bun/shell/shell-property-callback-crash.test.ts` at line 37, Remove
the negative assertion that checks stderr for "runtime error" by deleting the
expect(stderr).not.toContain("runtime error"); line in the test (the assertion
that references stderr and .not.toContain("runtime error")). Rely solely on the
existing exit code assertion (the exit code check/assertion in the test) as the
crash indicator, so no additional checks against stderr are performed.
|
Newest first ✅ 17f1a — Looks good! Reviewed 2 files across Previous reviews🟡 97745 — 1 issue(s) found
Note: This issue was already flagged by CodeRabbit in an existing review thread. No duplicate inline comment posted. |
The exit code check is the reliable crash indicator; negative string assertions against stderr won't catch regressions in CI. https://claude.ai/code/session_01UK81UJuPkCGjry9QgUrLRk
Summary
Bun.$(or other PropertyCallback-backed properties) during/after a stack overflow exceptionconstructBunShell,defaultBunSQLObject,constructBunSQLObject) returned{}(empty JSValue, encoded as0x0) on exception. JSC'sreifyStaticPropertypasses this value toputDirect(), which callsisGetterSetter()on it. The empty JSValue passes theisCell()check but yields a null cell pointer, causing the crash.jsUndefined()instead, which has tag bits set soisCell()returns false, avoiding the null dereference. The pending exception still propagates normally.Crash reproduction
Test plan
test/js/bun/shell/shell-property-callback-crash.test.tsthat reproduces the crash scenariobun bd testand fails withUSE_SYSTEM_BUN=1