fix(scripts): reject unsafe bounded response lengths

Reject unsafe decimal Content-Length values in shared scripts bounded-response helpers before streaming response bodies.\n\nValidation:\n- node --check scripts/lib/bounded-response.mjs\n- direct MJS repro for unsafe Content-Length\n- git diff --check origin/main...HEAD\n- autoreview clean, overall patch correct 0.88\n- exact-head release gate https://github.com/openclaw/openclaw/actions/runs/27845767740
This commit is contained in:
Vincent Koc
2026-06-20 04:04:40 +08:00
committed by GitHub
parent 4a0f497f16
commit c2c19a883d
3 changed files with 37 additions and 2 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ function parseContentLengthHeader(headers) {
return undefined;
}
const parsed = Number(raw);
return Number.isSafeInteger(parsed) ? parsed : undefined;
return Number.isSafeInteger(parsed) ? parsed : Number.POSITIVE_INFINITY;
}
async function readResponseChunk(reader, label, signal, markCanceled) {
+1 -1
View File
@@ -23,7 +23,7 @@ function parseContentLengthHeader(headers: Headers): number | undefined {
return undefined;
}
const parsed = Number(raw);
return Number.isSafeInteger(parsed) ? parsed : undefined;
return Number.isSafeInteger(parsed) ? parsed : Number.POSITIVE_INFINITY;
}
async function readResponseChunk(
+35
View File
@@ -98,4 +98,39 @@ describe("scripts bounded response reader", () => {
expect(canceled).toBe(true);
},
);
it.each(helpers)(
"rejects unsafe decimal %s content-length values before reading",
async (_name, read) => {
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<ReadableStreamReadResult<Uint8Array>>(() => {});
},
async cancel() {
canceled = true;
},
releaseLock() {},
};
},
},
} as unknown as Response;
await expect(read(response, "probe", 16)).rejects.toThrow(
"probe response body exceeded 16 bytes",
);
expect(readStarted).toBe(false);
expect(canceled).toBe(true);
},
);
});