fix(signal): cancel unread body when declared archive length exceeds cap (#117665)

This commit is contained in:
zengLingbiao
2026-08-02 07:25:32 +08:00
committed by GitHub
parent b2278f3d10
commit e8a158e4f5
2 changed files with 20 additions and 0 deletions
@@ -291,6 +291,25 @@ describe("downloadToFile", () => {
expect(cancel).toHaveBeenCalledOnce();
});
it("cancels the response body when the declared length exceeds the download cap", async () => {
const response = new Response("archive", {
status: 200,
headers: { "content-length": "12" },
});
const cancel = vi.spyOn(response.body!, "cancel").mockRejectedValueOnce(new Error("closed"));
fetchWithSsrFGuardMock.mockResolvedValue({ response, release: vi.fn() });
await withTempFile(async (filePath) => {
await expect(
downloadToFile("https://example.com/signal-cli.tgz", filePath, 5, 8),
).rejects.toThrow("declared 12");
await expectPathMissing(filePath);
});
expect(cancel).toHaveBeenCalledOnce();
});
it("downloads through the SSRF guard with an explicit timeout", async () => {
const fetchResult = okDownloadResponse("archive");
fetchWithSsrFGuardMock.mockResolvedValue(fetchResult);
@@ -194,6 +194,7 @@ export async function downloadToFile(
? Number(trimmedLength)
: Number.NaN;
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
await cancelUnusedResponseBody(response);
throw new Error(
`signal-cli archive exceeds the ${maxBytes}-byte download cap (declared ${declaredLength}).`,
);