-
Notifications
You must be signed in to change notification settings - Fork 5k
Fix four crash/correctness bugs: node:vm link(), Worker name, FFI threadsafe callbacks, sliced Bun.file #34140
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
8482bd4
310fdea
363337e
aa820f1
0705bb3
4b9b39b
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 | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -633,3 +633,58 @@ test.skipIf(!isASAN).each(["Blob", "File"] as const)( | |||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| // File-backed twin of "slice bounds are respected when streaming and serving" | ||||||||||||||||||||||||||||||||||||||||
| // above: the File arm of resolve_size()/resolved_size() must not widen a | ||||||||||||||||||||||||||||||||||||||||
| // sliced Bun.file() to the end of the file either. | ||||||||||||||||||||||||||||||||||||||||
| describe("file-backed slice bounds are respected when streaming and serving", () => { | ||||||||||||||||||||||||||||||||||||||||
| test("Bun.file(path).slice(start, end) streams only the slice", async () => { | ||||||||||||||||||||||||||||||||||||||||
| using dir = tempDir("blob-file-slice", { "data.txt": "0123456789".repeat(10) }); | ||||||||||||||||||||||||||||||||||||||||
| const s = Bun.file(`${dir}/data.txt`).slice(3, 7); | ||||||||||||||||||||||||||||||||||||||||
| expect(await new Response(s).text()).toBe("3456"); | ||||||||||||||||||||||||||||||||||||||||
| // Streaming must not mutate the slice either. | ||||||||||||||||||||||||||||||||||||||||
| expect(s.size).toBe(4); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| let streamed = 0; | ||||||||||||||||||||||||||||||||||||||||
| for await (const chunk of new Response(Bun.file(`${dir}/data.txt`).slice(0, 5)).body!) { | ||||||||||||||||||||||||||||||||||||||||
| streamed += chunk.length; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| expect(streamed).toBe(5); | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| test("content-length of a sliced Bun.file response body", async () => { | ||||||||||||||||||||||||||||||||||||||||
| using dir = tempDir("blob-file-slice-cl", { "data.txt": "0123456789".repeat(10) }); | ||||||||||||||||||||||||||||||||||||||||
| await using server = Bun.serve({ | ||||||||||||||||||||||||||||||||||||||||
| port: 0, | ||||||||||||||||||||||||||||||||||||||||
| fetch: () => new Response(Bun.file(`${dir}/data.txt`).slice(3, 7)), | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const head = await fetch(server.url, { method: "HEAD" }); | ||||||||||||||||||||||||||||||||||||||||
| expect(head.headers.get("content-length")).toBe("4"); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const get = await fetch(server.url); | ||||||||||||||||||||||||||||||||||||||||
| expect(get.headers.get("content-length")).toBe("4"); | ||||||||||||||||||||||||||||||||||||||||
| expect(await get.text()).toBe("3456"); | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| test("structuredClone keeps the slice size and does not mutate the original", async () => { | ||||||||||||||||||||||||||||||||||||||||
| using dir = tempDir("blob-file-slice-clone", { "data.txt": "0123456789".repeat(10) }); | ||||||||||||||||||||||||||||||||||||||||
| const s = Bun.file(`${dir}/data.txt`).slice(0, 5); | ||||||||||||||||||||||||||||||||||||||||
| expect(s.size).toBe(5); | ||||||||||||||||||||||||||||||||||||||||
| const clone = structuredClone(s); | ||||||||||||||||||||||||||||||||||||||||
| expect(clone.size).toBe(5); | ||||||||||||||||||||||||||||||||||||||||
| expect(s.size).toBe(5); | ||||||||||||||||||||||||||||||||||||||||
| expect(await clone.text()).toBe("01234"); | ||||||||||||||||||||||||||||||||||||||||
| expect(await s.text()).toBe("01234"); | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| test("slice end beyond EOF clamps to the file size", async () => { | ||||||||||||||||||||||||||||||||||||||||
| using dir = tempDir("blob-file-slice-eof", { "data.txt": "0123456789" }); | ||||||||||||||||||||||||||||||||||||||||
| const s = Bun.file(`${dir}/data.txt`).slice(5, 5000); | ||||||||||||||||||||||||||||||||||||||||
| expect(await new Response(s).text()).toBe("56789"); | ||||||||||||||||||||||||||||||||||||||||
| const clone = structuredClone(s); | ||||||||||||||||||||||||||||||||||||||||
| expect(await clone.text()).toBe("56789"); | ||||||||||||||||||||||||||||||||||||||||
| // Serializing resolves the original's size, clamping the window to EOF. | ||||||||||||||||||||||||||||||||||||||||
| expect(s.size).toBe(5); | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+681
to
+689
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 Add a This test only checks decoded content, which passes regardless of whether ✅ Suggested addition const clone = structuredClone(s);
expect(await clone.text()).toBe("56789");
+ expect(clone.size).toBe(5);
// Serializing resolves the original's size, clamping the window to EOF.
expect(s.size).toBe(5);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
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 | 🔵 Trivial | ⚡ Quick win
Preserve crash diagnostics from the subprocess.
The test captures
stderrbut discards it, so an ASAN/JSC crash may surface only as a generic stdout or exit-code mismatch. Include stderr and signal information in the failure outcome while keeping the success assertion focused on"done"and exit code0.Based on learnings, worker-thread crash-detection tests should preserve stdout, stderr, exitCode, and signalCode together.
🤖 Prompt for AI Agents
Source: Learnings