-
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 1 commit
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,26 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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");`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Assert that Line 591 discards the catch result. If Track whether the access throws and fail before printing As per coding guidelines, tests must prove their preconditions and must not silently swallow failures. Proposed fix- `globalThis.Symbol = NaN; Bun.inspect(Bun); try { Bun.sql } catch {} console.log("ok");`,
+ `globalThis.Symbol = NaN; Bun.inspect(Bun); let sqlThrew = false; try { Bun.sql } catch { sqlThrew = true; } if (!sqlThrew) throw new Error("Bun.sql did not throw"); console.log("ok");`,📝 Committable suggestion
Suggested change
🤖 Prompt for AI AgentsSource: Coding guidelines |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: bunEnv, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stdout: "pipe", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stderr: "pipe", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check warning on line 597 in test/js/bun/util/inspect.test.js
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+587
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. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win Drain Line 595 configures stderr as a pipe, but Line 597 reads only stdout and Read As per coding guidelines, subprocess tests must drain stdout, stderr, and process exit concurrently. Proposed fix- const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);
+ const [stdout, , exitCode] = await Promise.all([
+ proc.stdout.text(),
+ proc.stderr.text(),
+ proc.exited,
+ ]);📝 Committable suggestion
Suggested change
🤖 Prompt for AI AgentsSource: Coding guidelines
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.
If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code