UNPKG

taglib-wasm

Version:

TagLib for TypeScript platforms: Deno, Node.js, Bun, Electron, browsers, and Cloudflare Workers

191 lines (190 loc) 5.29 kB
import { decode } from "@msgpack/msgpack"; const MSGPACK_DECODE_OPTIONS = { // Use integers instead of BigInt for performance useBigInt64: false, // Enable extension types for custom data extensionCodec: void 0, // Will be set up below if needed // Maximum decode iterations for safety maxStrLength: 1e6, // 1MB max string maxBinLength: 5e7, // 50MB max binary (for large album art) maxArrayLength: 1e4, // Reasonable array limit maxMapLength: 1e3, // Reasonable object limit maxExtLength: 5e7 // 50MB max extension }; function decodeTagData(msgpackBuffer) { try { const decoded = decode(msgpackBuffer, MSGPACK_DECODE_OPTIONS); return decoded; } catch (error) { throw new Error(`Failed to decode MessagePack tag data: ${error}`); } } function decodeAudioProperties(msgpackBuffer) { try { const decoded = decode(msgpackBuffer, MSGPACK_DECODE_OPTIONS); return decoded; } catch (error) { throw new Error(`Failed to decode MessagePack audio properties: ${error}`); } } function decodePropertyMap(msgpackBuffer) { try { const decoded = decode(msgpackBuffer, MSGPACK_DECODE_OPTIONS); return decoded; } catch (error) { throw new Error(`Failed to decode MessagePack property map: ${error}`); } } function decodePicture(msgpackBuffer) { try { const decoded = decode(msgpackBuffer, MSGPACK_DECODE_OPTIONS); const picture = decoded; if (picture.data && !(picture.data instanceof Uint8Array)) { picture.data = new Uint8Array(picture.data); } return picture; } catch (error) { throw new Error(`Failed to decode MessagePack picture data: ${error}`); } } function decodePictureArray(msgpackBuffer) { try { const decoded = decode(msgpackBuffer, MSGPACK_DECODE_OPTIONS); const pictures = decoded; return pictures.map((picture) => { if (picture.data && !(picture.data instanceof Uint8Array)) { picture.data = new Uint8Array(picture.data); } return picture; }); } catch (error) { throw new Error(`Failed to decode MessagePack picture array: ${error}`); } } function decodeMessagePack(msgpackBuffer, options = {}) { try { const mergedOptions = { ...MSGPACK_DECODE_OPTIONS, ...options }; const decoded = decode(msgpackBuffer, mergedOptions); return decoded; } catch (error) { throw new Error(`Failed to decode MessagePack data: ${error}`); } } function decodeMessagePackAuto(msgpackBuffer) { try { const decoded = decode(msgpackBuffer, MSGPACK_DECODE_OPTIONS); if (decoded && typeof decoded === "object") { if ("bitrate" in decoded && "sampleRate" in decoded && "length" in decoded) { return decoded; } if ("mimeType" in decoded && "data" in decoded) { if (decoded.data && !(decoded.data instanceof Uint8Array)) { decoded.data = new Uint8Array(decoded.data); } return decoded; } if ("title" in decoded || "artist" in decoded || "album" in decoded) { return decoded; } if (Object.values(decoded).every((value) => Array.isArray(value))) { return decoded; } } return decoded; } catch (error) { throw new Error( `Failed to decode MessagePack data with auto-detection: ${error}` ); } } function isValidMessagePack(buffer) { try { decode(buffer, { ...MSGPACK_DECODE_OPTIONS, maxStrLength: 1e3, maxBinLength: 1e3, maxArrayLength: 100, maxMapLength: 100, maxExtLength: 1e3 }); return true; } catch { return false; } } function getMessagePackInfo(buffer) { const info = { isValid: false, approximateSize: buffer.length, type: "unknown" }; if (buffer.length === 0) { return info; } try { const decoded = decode(buffer, { ...MSGPACK_DECODE_OPTIONS, maxStrLength: 100, maxBinLength: 100, maxArrayLength: 10, maxMapLength: 10, maxExtLength: 100 }); info.isValid = true; if (Array.isArray(decoded)) { info.type = "array"; } else if (decoded instanceof Uint8Array) { info.type = "binary"; } else if (typeof decoded === "object" && decoded !== null) { info.type = "map"; } else if (typeof decoded === "string") { info.type = "string"; } else if (typeof decoded === "number") { info.type = "number"; } else if (typeof decoded === "boolean") { info.type = "boolean"; } else if (decoded === null) { info.type = "null"; } } catch { } return info; } function decodeFastTagData(msgpackBuffer) { try { const decoded = decode(msgpackBuffer, { ...MSGPACK_DECODE_OPTIONS, // Smaller limits for faster processing maxStrLength: 1e4, maxArrayLength: 100, maxMapLength: 50 }); return { title: decoded.title, artist: decoded.artist, album: decoded.album, year: decoded.year, track: decoded.track }; } catch (error) { throw new Error(`Failed to decode fast tag data: ${error}`); } } export { decodeAudioProperties, decodeFastTagData, decodeMessagePack, decodeMessagePackAuto, decodePicture, decodePictureArray, decodePropertyMap, decodeTagData, getMessagePackInfo, isValidMessagePack };