-
Notifications
You must be signed in to change notification settings - Fork 5k
Fix debug assertion crashes when lazy Bun properties throw during property enumeration #37307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -579,6 +579,22 @@ it("Bun.inspect huge sparse array summarizes holes without iterating them", asyn | |
| }); | ||
| }); | ||
|
|
||
| it("Bun.inspect(Bun) does not crash when the Symbol global is clobbered", async () => { | ||
| // Lazy properties on the Bun object (Bun.$, Bun.sql) evaluate internal | ||
| // modules that call Symbol() at the top level, so reading them throws when | ||
| // the global Symbol is overwritten. The pending exception must not leak into | ||
| // the lookup of the next property during the inspect walk. | ||
| await using proc = Bun.spawn({ | ||
| cmd: [bunExe(), "-e", `globalThis.Symbol = NaN; Bun.inspect(Bun); try { Bun.sql } catch {} console.log("ok");`], | ||
| env: bunEnv, | ||
| stdout: "pipe", | ||
| stderr: "pipe", | ||
| }); | ||
| const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]); | ||
|
Comment on lines
+594
to
+597
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The test sets Extended reasoning...What the issue isThe new test at inspect.test.js:582-600 spawns a subprocess with
It also diverges from the immediately-preceding test in the same file ("Bun.inspect huge sparse array…", lines 571-579), which follows this pattern exactly and asserts on a combined Step-by-step walk-through
If the child wrote ≥64KB to stderr, its Why this still mattersBeyond the (small) deadlock risk, dropping the stderr assertion loses diagnostic value for exactly the failure mode this test guards against. The bug being fixed is a debug-build assertion abort, and JSC's Why existing code doesn't prevent itNothing in the test harness auto-drains piped streams; if you request Suggested fixMatch the preceding test's shape: const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect({ stdout, stderr, exitCode }).toEqual({ stdout: "ok\n", stderr: "", exitCode: 0 });Alternatively, if stderr is intentionally uninteresting, drop |
||
| expect(stdout).toBe("ok\n"); | ||
| expect(exitCode).toBe(0); | ||
| }); | ||
|
|
||
| describe("console.logging function displays async and generator names", async () => { | ||
| const cases = [ | ||
| function () {}, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Drain
proc.stderrbefore waiting for process exit.Line 595 configures stderr as a pipe, but Line 597 reads only stdout and
proc.exited. If the child reproduces the debug or ASAN failure and writes enough diagnostics, the stderr pipe can fill and block the child. The test can then hang instead of reporting the failure.Read
proc.stderr.text()in the samePromise.allas stdout andproc.exited.As per coding guidelines, subprocess tests must drain stdout, stderr, and process exit concurrently.
Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents
Source: Coding guidelines