Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/js/ahead-of-time/node/_http_common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// What the compiler reads in place of src/js/node/_http_common.ts, which `bun run` evaluates. The two do the same.
// Written against that file with the SHA-256 e9bcb64b690623cf8e8b8ce199a3326e23a7430bdeed5fd855a1902f2798e2d8.
// Written against that file with the SHA-256 0d1fd706eaf5fdc6a02e5bf7ea7be7c963c340fb52ec8474fce8f9a9e74c2265.
// When that file changes, bring the change here and write the new hash: test/internal/second-texts-of-modules.test.ts.

// This is a port of Node.js's lib/_http_common.js
Expand Down Expand Up @@ -183,7 +183,7 @@ function parserOnHeadersComplete(

// If parser.maxHeaderPairs <= 0 assume that there's no limit.
const maxHeaderPairs = parser.maxHeaderPairs;
if (maxHeaderPairs > 0) n = Math.min(n, maxHeaderPairs);
if (maxHeaderPairs > 0) n = $min(n, maxHeaderPairs);

incoming._addHeaderLines(headers, n);

Expand Down
2 changes: 1 addition & 1 deletion src/js/node/_http_common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ function parserOnHeadersComplete(

// If parser.maxHeaderPairs <= 0 assume that there's no limit.
const maxHeaderPairs = parser.maxHeaderPairs;
if (maxHeaderPairs > 0) n = Math.min(n, maxHeaderPairs);
if (maxHeaderPairs > 0) n = $min(n, maxHeaderPairs);
Comment thread
robobun marked this conversation as resolved.
Resolved

incoming._addHeaderLines(headers, n);

Expand Down
42 changes: 42 additions & 0 deletions test/js/node/http/node-http-primoridals.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { afterEach, expect, test } from "bun:test";
import { bunEnv, bunExe } from "harness";
import { once } from "node:events";
import type { AddressInfo } from "node:net";
import { text } from "node:stream/consumers";
Expand Down Expand Up @@ -196,3 +197,44 @@ test("does not read URL from globalThis", async () => {
globalThis.URL = URL;
}
});

// The response header count is bounded with the engine's own min(), so a
// user-patched Math.min cannot make IncomingMessage read past the flat
// [name, value, ...] header array.
test("a patched Math.min does not reach IncomingMessage header parsing", async () => {
await using proc = Bun.spawn({
cmd: [
bunExe(),
"-e",
`
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
const http = require("http");
const server = http.createServer((req, res) => {
res.setHeader("x-server", "1");
res.end("ok");
});
server.listen(0, "127.0.0.1", () => {
const origMin = Math.min;
Math.min = (...args) => origMin(...args) + 1;
process.on("uncaughtException", err => {
console.log("UNCAUGHT:", err.message);
process.exit(1);
});
http.get({ host: "127.0.0.1", port: server.address().port, headers: { "x-h": "v" } }, res => {
res.resume();
res.on("end", () => {
Math.min = origMin;
console.log("client: got", res.statusCode, res.headers["x-server"]);
server.close();
});
});
});
`,
],
env: bunEnv,
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(stdout).toBe("client: got 200 1\n");
expect(stderr).toBe("");
expect(exitCode).toBe(0);
});
Loading