UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

52 lines (51 loc) • 2.65 kB
/** * Bounded ZIP entry reading, shared by every processor that opens a ZIP. * * Extracted from ArchiveProcessor because the Office formats are ZIPs too: * .pptx and .odt read their entries directly and so can be handed the same * bomb, and need the same refusal. One implementation rather than three means * a correction to the guard lands everywhere at once. * * .docx and .xlsx deliberately do NOT use this. mammoth and exceljs unzip for * themselves and were measured refusing a 400MB bomb at 46MB and 53MB peak, * so wrapping them in a pre-scan bought no safety and roughly tripled the cost * of every ordinary document. * * @module processors/archive/zipEntryReader */ import type { ArchiveEntryReadResult, BoundedZipEntry } from "../../types/index.js"; /** ZIP compression methods this reader handles (APPNOTE 4.4.5). */ export declare const ZIP_METHOD_STORED = 0; export declare const ZIP_METHOD_DEFLATED = 8; /** * Whether a zlib rejection is the output bound firing rather than bad input. * * `maxOutputLength` aborts an inflate the moment its output would pass the cap, * which is the whole point — but it surfaces as a plain `RangeError`, and a * bomb reported as "failed to decompress" reads as a corrupt upload and invites * the user to send it again. It will fail identically every time. * * Keyed on `code`, not the message: the message embeds a byte count. */ export declare const isDecompressionBoundExceeded: (error: unknown) => boolean; /** * Read one ZIP entry's bytes without trusting the size it declares. * * `entry.getData()` cannot be used for this. It sizes its output buffer from * the central-directory `size` field, which the archive author chooses, and * adm-zip only arms its own guard when that field is positive: * * const option = version >= 15 && expectedLength > 0 * ? { maxOutputLength: expectedLength } : {}; * * So an entry declaring 0 disables the bound and the caller's `size > maxSize` * check in one move — `0 > 5MB` is false, and the inflate then runs uncapped. * The declared size is the attack, so nothing here may depend on it: the cap * comes from our own limit and is handed to the decoder. * * CRC is verified on both paths rather than dropped, so bypassing `getData()` * does not also quietly lose its corruption check — a STORED entry is copied * out rather than decoded, but it can be damaged just the same. It detects * damage, not malice — the CRC field is attacker-controlled too. */ export declare function readZipEntryWithinLimit(entry: BoundedZipEntry, maxBytes: number, zlibModule: typeof import("zlib")): ArchiveEntryReadResult;