-
Notifications
You must be signed in to change notification settings - Fork 4.7k
fix(zlib): prevent use-after-free in WorkPool compression operations #28250
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
2dbecdd
7b3a1c5
5334fb6
18f2f72
469a0d4
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 |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| import { expect, test } from "bun:test"; | ||
| import { bunEnv, bunExe } from "harness"; | ||
|
|
||
| // Test that piping HTTP responses through zlib.createGunzip() does not crash. | ||
| // Issue #22567: use-after-free when GC collects input/output buffers during | ||
| // async WorkPool decompression. | ||
| test("pipe HTTP response through createGunzip without crash", async () => { | ||
| await using proc = Bun.spawn({ | ||
| cmd: [ | ||
| bunExe(), | ||
| "-e", | ||
| ` | ||
| const http = require("node:http"); | ||
| const zlib = require("node:zlib"); | ||
|
|
||
| const server = http.createServer((req, res) => { | ||
| res.writeHead(200, { "Content-Type": "application/octet-stream" }); | ||
| const gzip = zlib.createGzip(); | ||
| gzip.pipe(res); | ||
| for (let i = 0; i < 50; i++) { | ||
| gzip.write("Line " + i + ": " + "x".repeat(80) + "\\n"); | ||
| } | ||
| gzip.end(); | ||
| }); | ||
|
|
||
| server.listen(0, () => { | ||
| const port = server.address().port; | ||
| let completed = 0; | ||
| const total = 3; | ||
|
|
||
| for (let i = 0; i < total; i++) { | ||
| http.get("http://localhost:" + port + "/", (response) => { | ||
| const gunzip = zlib.createGunzip(); | ||
| const stream = response.pipe(gunzip); | ||
| let data = ""; | ||
| stream.on("data", (chunk) => { data += chunk.toString(); }); | ||
| stream.on("end", () => { | ||
| Bun.gc(true); | ||
| completed++; | ||
| if (completed >= total) { | ||
| console.log("OK"); | ||
| server.close(() => process.exit(0)); | ||
| } | ||
| }); | ||
| stream.on("error", (err) => { | ||
| console.error("error:", err.message); | ||
| process.exit(1); | ||
| }); | ||
| }).on("error", (err) => { | ||
| console.error("request error:", err.message); | ||
| process.exit(1); | ||
| }); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| }); | ||
| `, | ||
| ], | ||
| env: bunEnv, | ||
| stderr: "pipe", | ||
| }); | ||
|
|
||
| const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); | ||
|
|
||
| if (exitCode !== 0) { | ||
| console.log("stderr:", stderr); | ||
| } | ||
| expect(stdout.trim()).toBe("OK"); | ||
| expect(exitCode).toBe(0); | ||
| }, 15_000); | ||
|
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 an explicit Extended reasoning...What the issue isThe regression test at The specific codeLine 68 reads: }, 15_000);This is the closing of the Why this mattersWhile this is a convention/style violation rather than a functional bug, the CLAUDE.md rule exists for good reason: Bun's test runner already provides default timeouts, and explicit timeouts create maintenance burden and inconsistency across the test suite. The rule is marked as "CRITICAL" in the project guidelines. ImpactThe test will still pass correctly with or without the explicit timeout. This is purely a convention violation. It's worth noting that ~20 other regression test files also have explicit timeouts, so this is a widespread pattern, but new code should follow the documented convention. How to fixSimply remove the }, 15_000);to: });Bun's default test timeout will handle the case where the test hangs. |
||
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.
Use
Buffer.alloc(...).toString()for repetitive test payload content.Line 21 currently uses
"x".repeat(80), which conflicts with repository testing conventions.β»οΈ Suggested fix
As per coding guidelines: "Use
Buffer.alloc(count, fill).toString()instead of'A'.repeat(count)to create repetitive strings in tests."π Committable suggestion
π€ Prompt for AI Agents