fix: detect HEIC/HEIF from raw Base64 image signatures
This commit is contained in:
36
src/tools/look-at/mime-type-inference.test.ts
Normal file
36
src/tools/look-at/mime-type-inference.test.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { extractBase64Data, inferMimeTypeFromBase64, inferMimeTypeFromFilePath } from "./mime-type-inference"
|
||||
|
||||
describe("mime type inference", () => {
|
||||
test("returns MIME from data URL prefix", () => {
|
||||
const mime = inferMimeTypeFromBase64("data:image/heic;base64,AAAAGGZ0eXBoZWlj")
|
||||
expect(mime).toBe("image/heic")
|
||||
})
|
||||
|
||||
test("detects HEIC from raw base64 magic bytes", () => {
|
||||
const heicHeader = Buffer.from("00000018667479706865696300000000", "hex").toString("base64")
|
||||
const mime = inferMimeTypeFromBase64(heicHeader)
|
||||
expect(mime).toBe("image/heic")
|
||||
})
|
||||
|
||||
test("detects HEIF from raw base64 magic bytes", () => {
|
||||
const heifHeader = Buffer.from("00000018667479706865696600000000", "hex").toString("base64")
|
||||
const mime = inferMimeTypeFromBase64(heifHeader)
|
||||
expect(mime).toBe("image/heif")
|
||||
})
|
||||
|
||||
test("falls back to png when base64 signature is unknown", () => {
|
||||
const mime = inferMimeTypeFromBase64("dW5rbm93biBiaW5hcnk=")
|
||||
expect(mime).toBe("image/png")
|
||||
})
|
||||
|
||||
test("infers heic from file extension", () => {
|
||||
const mime = inferMimeTypeFromFilePath("/tmp/photo.HEIC")
|
||||
expect(mime).toBe("image/heic")
|
||||
})
|
||||
|
||||
test("extracts raw base64 data from data URL", () => {
|
||||
const base64 = extractBase64Data("data:image/png;base64,abc123")
|
||||
expect(base64).toBe("abc123")
|
||||
})
|
||||
})
|
||||
@@ -8,12 +8,18 @@ export function inferMimeTypeFromBase64(base64Data: string): string {
|
||||
|
||||
try {
|
||||
const cleanData = base64Data.replace(/^data:[^;]+;base64,/, "")
|
||||
const header = atob(cleanData.slice(0, 16))
|
||||
const header = Buffer.from(cleanData.slice(0, 256), "base64").toString("binary")
|
||||
|
||||
if (header.startsWith("\x89PNG")) return "image/png"
|
||||
if (header.startsWith("\xFF\xD8\xFF")) return "image/jpeg"
|
||||
if (header.startsWith("GIF8")) return "image/gif"
|
||||
if (header.startsWith("RIFF") && header.includes("WEBP")) return "image/webp"
|
||||
if (header.includes("ftypheic") || header.includes("ftypheix") || header.includes("ftyphevc") || header.includes("ftyphevx")) {
|
||||
return "image/heic"
|
||||
}
|
||||
if (header.includes("ftypheif") || header.includes("ftypmif1") || header.includes("ftypmsf1")) {
|
||||
return "image/heif"
|
||||
}
|
||||
if (header.startsWith("%PDF")) return "application/pdf"
|
||||
} catch {
|
||||
// invalid base64 - fall through
|
||||
|
||||
Reference in New Issue
Block a user