Skip to content
Merged
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
10 changes: 9 additions & 1 deletion packages/client-runtime/src/projectFaviconCache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,19 @@ describe("project favicon image loader", () => {
await expect(load(url, signal())).rejects.toThrow("too large");
expect(pulled).toBeLessThan(PROJECT_FAVICON_MAX_SOURCE_BYTES / chunk.byteLength + 3);
expect(downscale).not.toHaveBeenCalled();
let cancelled = false;
const declaredStream = new ReadableStream<Uint8Array>({
cancel() {
cancelled = true;
},
});
const declared = loader(
new Response("x", {
new Response(declaredStream, {
headers: { "content-type": "image/png", "content-length": String(2 ** 40) },
}),
);
await expect(declared.load(url, signal())).rejects.toThrow("too large");
expect(cancelled).toBe(true);
expect(declared.downscale).not.toHaveBeenCalled();
});
});
5 changes: 4 additions & 1 deletion packages/client-runtime/src/projectFaviconCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ export interface ProjectFaviconStorage {

async function readBounded(response: Response, maxBytes: number) {
const declared = Number(response.headers.get("content-length"));
if (declared > maxBytes) throw new Error("Project icon is too large to decode.");
if (declared > maxBytes) {
await response.body?.cancel().catch(() => {});
throw new Error("Project icon is too large to decode.");
}
if (!response.body) {
const bytes = new Uint8Array<ArrayBuffer>(await response.arrayBuffer());
if (bytes.byteLength > maxBytes) throw new Error("Project icon is too large to decode.");
Expand Down
Loading