Gateway: follow up HEIC input image handling (#38146)

* Media: scope HEIC MIME sniffing

* Media: hermeticize HEIC input tests

* Gateway: fix HEIC image budget accounting

* Gateway: add HEIC image budget regression test

* Changelog: note HEIC follow-up fix
This commit is contained in:
Vincent Koc
2026-03-06 11:53:59 -05:00
committed by GitHub
parent f9d86b9256
commit 9521e61a22
5 changed files with 116 additions and 10 deletions

View File

@@ -2,6 +2,7 @@ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const fetchWithSsrFGuardMock = vi.fn();
const convertHeicToJpegMock = vi.fn();
const detectMimeMock = vi.fn();
vi.mock("../infra/net/fetch-guard.js", () => ({
fetchWithSsrFGuard: (...args: unknown[]) => fetchWithSsrFGuardMock(...args),
@@ -11,6 +12,10 @@ vi.mock("./image-ops.js", () => ({
convertHeicToJpeg: (...args: unknown[]) => convertHeicToJpegMock(...args),
}));
vi.mock("./mime.js", () => ({
detectMime: (...args: unknown[]) => detectMimeMock(...args),
}));
async function waitForMicrotaskTurn(): Promise<void> {
await new Promise<void>((resolve) => queueMicrotask(resolve));
}
@@ -31,6 +36,7 @@ beforeEach(() => {
describe("HEIC input image normalization", () => {
it("converts base64 HEIC images to JPEG before returning them", async () => {
const normalized = Buffer.from("jpeg-normalized");
detectMimeMock.mockResolvedValueOnce("image/heic");
convertHeicToJpegMock.mockResolvedValueOnce(normalized);
const image = await extractImageContentFromSource(
@@ -67,6 +73,7 @@ describe("HEIC input image normalization", () => {
finalUrl: "https://example.com/photo.heic",
});
const normalized = Buffer.from("jpeg-url-normalized");
detectMimeMock.mockResolvedValueOnce("image/heic");
convertHeicToJpegMock.mockResolvedValueOnce(normalized);
const image = await extractImageContentFromSource(
@@ -91,6 +98,31 @@ describe("HEIC input image normalization", () => {
});
expect(release).toHaveBeenCalledTimes(1);
});
it("keeps declared MIME for non-HEIC images without sniffing", async () => {
const image = await extractImageContentFromSource(
{
type: "base64",
data: Buffer.from("png-like").toString("base64"),
mediaType: "image/png",
},
{
allowUrl: false,
allowedMimes: new Set(["image/png"]),
maxBytes: 1024 * 1024,
maxRedirects: 0,
timeoutMs: 1,
},
);
expect(detectMimeMock).not.toHaveBeenCalled();
expect(convertHeicToJpegMock).not.toHaveBeenCalled();
expect(image).toEqual({
type: "image",
data: Buffer.from("png-like").toString("base64"),
mimeType: "image/png",
});
});
});
describe("fetchWithGuard", () => {