diff --git a/src/hooks/read-image-resizer/image-dimensions.test.ts b/src/hooks/read-image-resizer/image-dimensions.test.ts index 47beb2714..72fa2dbb7 100644 --- a/src/hooks/read-image-resizer/image-dimensions.test.ts +++ b/src/hooks/read-image-resizer/image-dimensions.test.ts @@ -28,6 +28,13 @@ function createGifDataUrl(width: number, height: number): string { return `data:image/gif;base64,${buf.toString("base64")}` } +function createLargePngDataUrl(width: number, height: number, extraBase64Chars: number): string { + const baseDataUrl = createPngDataUrl(width, height) + const base64Data = baseDataUrl.slice(baseDataUrl.indexOf(",") + 1) + const paddedBase64 = `${base64Data}${"A".repeat(extraBase64Chars)}` + return `data:image/png;base64,${paddedBase64}` +} + describe("parseImageDimensions", () => { it("parses PNG 1x1 dimensions", () => { //#given @@ -51,6 +58,17 @@ describe("parseImageDimensions", () => { expect(result).toEqual({ width: 3000, height: 2000 }) }) + it("parses PNG dimensions from a very large base64 payload", () => { + //#given + const dataUrl = createLargePngDataUrl(4096, 2160, 10 * 1024 * 1024) + + //#when + const result = parseImageDimensions(dataUrl, "image/png") + + //#then + expect(result).toEqual({ width: 4096, height: 2160 }) + }) + it("parses GIF 1x1 dimensions", () => { //#given const dataUrl = GIF_1X1_DATA_URL diff --git a/src/hooks/read-image-resizer/image-dimensions.ts b/src/hooks/read-image-resizer/image-dimensions.ts index 56088e97b..0bb411905 100644 --- a/src/hooks/read-image-resizer/image-dimensions.ts +++ b/src/hooks/read-image-resizer/image-dimensions.ts @@ -2,6 +2,9 @@ import type { ImageDimensions } from "./types" import { extractBase64Data } from "../../tools/look-at/mime-type-inference" +const HEADER_BYTES = 32_768 +const HEADER_BASE64_CHARS = Math.ceil(HEADER_BYTES / 3) * 4 + function toImageDimensions(width: number, height: number): ImageDimensions | null { if (!Number.isFinite(width) || !Number.isFinite(height)) { return null @@ -157,7 +160,8 @@ export function parseImageDimensions(base64DataUrl: string, mimeType: string): I return null } - const buffer = Buffer.from(rawBase64, "base64") + const headerBase64 = rawBase64.length > HEADER_BASE64_CHARS ? rawBase64.slice(0, HEADER_BASE64_CHARS) : rawBase64 + const buffer = Buffer.from(headerBase64, "base64") if (buffer.length === 0) { return null }