diff --git a/scripts/e2e/lib/bounded-response-text.mjs b/scripts/e2e/lib/bounded-response-text.mjs index 70a59816d26..7bb05033fac 100644 --- a/scripts/e2e/lib/bounded-response-text.mjs +++ b/scripts/e2e/lib/bounded-response-text.mjs @@ -17,7 +17,7 @@ function parseContentLengthHeader(headers) { return undefined; } const parsed = Number(raw); - return Number.isSafeInteger(parsed) ? parsed : undefined; + return Number.isSafeInteger(parsed) ? parsed : Number.POSITIVE_INFINITY; } export async function readBoundedResponseText(response, label, byteLimit, timeoutPromise) { diff --git a/test/scripts/bounded-response-text.test.ts b/test/scripts/bounded-response-text.test.ts index cc06d818c15..1a4057b76ca 100644 --- a/test/scripts/bounded-response-text.test.ts +++ b/test/scripts/bounded-response-text.test.ts @@ -111,4 +111,36 @@ describe("scripts/e2e/lib/bounded-response-text.mjs", () => { expect(readStarted).toBe(true); expect(canceled).toBe(true); }); + + it("rejects unsafe decimal content-length values before reading", async () => { + let readStarted = false; + let canceled = false; + const response = { + headers: new Headers({ "content-length": "9007199254740993" }), + body: { + async cancel() { + canceled = true; + }, + getReader() { + return { + async read() { + readStarted = true; + return new Promise>(() => {}); + }, + async cancel() { + canceled = true; + }, + releaseLock() {}, + }; + }, + }, + }; + + await expect(readBoundedResponseText(response, "probe", 16)).rejects.toMatchObject({ + code: "ETOOBIG", + message: "probe response body exceeded 16 bytes", + }); + expect(readStarted).toBe(false); + expect(canceled).toBe(true); + }); });