UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

117 lines (116 loc) 4.63 kB
import { t as canonicalizeBase64 } from "./base64-l6yrCyHc.js"; //#region packages/media-core/src/inline-image-data-url.ts /** Prefix used to distinguish inline data URLs from remote/local image references. */ const INLINE_IMAGE_DATA_URL_PREFIX = "data:"; const IMAGE_SIGNATURES = [ { mime: "image/png", matches: (buffer) => buffer.length >= 8 && buffer[0] === 137 && buffer[1] === 80 && buffer[2] === 78 && buffer[3] === 71 && buffer[4] === 13 && buffer[5] === 10 && buffer[6] === 26 && buffer[7] === 10 }, { mime: "image/jpeg", matches: (buffer) => buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255 }, { mime: "image/webp", matches: (buffer) => buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP" }, { mime: "image/gif", matches: (buffer) => buffer.length >= 6 && (buffer.subarray(0, 6).toString("ascii") === "GIF87a" || buffer.subarray(0, 6).toString("ascii") === "GIF89a") }, { mime: "image/bmp", matches: (buffer) => buffer.length >= 2 && buffer[0] === 66 && buffer[1] === 77 } ]; const HEIC_BRANDS = new Set([ "heic", "heix", "hevc", "hevx", "heis", "heim", "hevm", "hevs" ]); const HEIF_BRANDS = new Set(["mif1", "msf1"]); const IMAGE_SIGNATURE_PREFIX_BASE64_CHARS = 128; const INLINE_IMAGE_DATA_URL_MIMES = new Set([ "image/png", "image/jpeg", "image/webp", "image/gif" ]); function startsWithDataUrl(value) { return value.slice(0, 5).toLowerCase() === INLINE_IMAGE_DATA_URL_PREFIX; } function sniffIsoBmffImageMime(buffer) { if (buffer.length < 12 || buffer.subarray(4, 8).toString("ascii") !== "ftyp") return; const brands = [buffer.subarray(8, 12).toString("ascii")]; for (let offset = 16; offset + 4 <= buffer.length; offset += 4) brands.push(buffer.subarray(offset, offset + 4).toString("ascii")); if (brands.some((brand) => HEIC_BRANDS.has(brand))) return "image/heic"; if (brands.some((brand) => HEIF_BRANDS.has(brand))) return "image/heif"; } /** Sniffs supported inline image formats from decoded bytes. */ function sniffInlineImageMime(buffer) { return IMAGE_SIGNATURES.find((signature) => signature.matches(buffer))?.mime ?? sniffIsoBmffImageMime(buffer); } function isImageMimeType(value) { return value.trim().toLowerCase().startsWith("image/"); } /** Canonicalizes trusted inline image base64 and rejects malformed or non-image payloads. */ function sanitizeInlineImageBase64(params) { if (!isImageMimeType(params.mimeType)) return; const canonicalPayload = canonicalizeBase64(params.base64); if (!canonicalPayload) return; const sniffedMimeType = sniffInlineImageMime(Buffer.from(canonicalPayload.slice(0, IMAGE_SIGNATURE_PREFIX_BASE64_CHARS), "base64")); if (!sniffedMimeType) return; return { mimeType: sniffedMimeType, base64: canonicalPayload }; } function parseInlineImageDataUrl(value) { if (!startsWithDataUrl(value)) return { metadata: [], payload: value }; const commaIndex = value.indexOf(","); if (commaIndex < 0) return; return { metadata: value.slice(5, commaIndex).split(";").map((part) => part.trim()), payload: value.slice(commaIndex + 1) }; } function metadataAllowsImageBase64(metadata) { const [mimeType, ...options] = metadata; return mimeType !== void 0 && isImageMimeType(mimeType) && options.some((part) => part.toLowerCase() === "base64"); } function sanitizeInlineImageDataUrlWithAllowedMimes(imageUrl, allowedMimes) { const parsed = parseInlineImageDataUrl(imageUrl); if (!parsed) return; if (parsed.metadata.length === 0) return imageUrl; if (!metadataAllowsImageBase64(parsed.metadata)) return; const [mimeType] = parsed.metadata; const sanitized = sanitizeInlineImageBase64({ mimeType: mimeType ?? "", base64: parsed.payload }); if (!sanitized) return; if (allowedMimes && !allowedMimes.has(sanitized.mimeType)) return; return `data:${sanitized.mimeType};base64,${sanitized.base64}`; } /** * Canonicalizes trusted inline image data URLs for persistence. * Accepts every image signature supported by `sanitizeInlineImageBase64`. */ function sanitizeInlineImageDataUrlForStorage(imageUrl) { return sanitizeInlineImageDataUrlWithAllowedMimes(imageUrl); } /** Canonicalizes provider-safe inline image data URLs and rejects unsupported formats. */ function sanitizeInlineImageDataUrl(imageUrl) { return sanitizeInlineImageDataUrlWithAllowedMimes(imageUrl, INLINE_IMAGE_DATA_URL_MIMES); } //#endregion export { sniffInlineImageMime as a, sanitizeInlineImageDataUrlForStorage as i, sanitizeInlineImageBase64 as n, sanitizeInlineImageDataUrl as r, INLINE_IMAGE_DATA_URL_PREFIX as t };