import { OpenXmlDecompressionBombError } from '../utils/exceptions'; /** Per-archive limits enforced during {@link openZip}. */ export interface DecompressionLimits { /** * Maximum decompressed bytes for a single archive entry. Default 512 MiB. * Legitimate xlsx sheets stay well below this even with millions of cells. */ maxEntryUncompressedBytes?: number; /** * Maximum decompressed bytes summed across every entry the caller reads. * Default 1 GiB. */ maxTotalUncompressedBytes?: number; /** * Maximum allowed `uncompressed / compressed` ratio for a single entry. * Default 1000. xml usually compresses 5–20×, but highly repetitive payloads * (long runs of zeros, sparse worksheets) can hit several hundred × * legitimately. Classic zip-bombs run 10 000× and up, so a 1000× ceiling * still catches them while admitting realistic content. The implementation * treats compressed sizes below 64 B as exempt — there's no amplification * budget worth policing on such small entries, and the absolute per-entry / * archive limits already cover them. */ maxCompressionRatio?: number; } /** Resolved limits with no `undefined` fields. */ export interface ResolvedDecompressionLimits { readonly maxEntryUncompressedBytes: number; readonly maxTotalUncompressedBytes: number; readonly maxCompressionRatio: number; } /** Default safeguards applied when the caller doesn't override them. */ export declare const DEFAULT_DECOMPRESSION_LIMITS: ResolvedDecompressionLimits; /** * `DecompressionLimits` plus the sentinel `false` to disable the guard. * Anything else is treated as "use defaults". */ export type DecompressionLimitsInput = DecompressionLimits | false | undefined; /** Returns null when the guard is disabled. */ export declare function resolveDecompressionLimits(input: DecompressionLimitsInput): ResolvedDecompressionLimits | null; /** * Per-archive byte accounting shared across every read of an archive opened * with the given limits. Tracks total inflated bytes so the cap is enforced * even when individual entries stay below the per-entry ceiling. */ export interface DecompressionBudget { readonly limits: ResolvedDecompressionLimits; totalInflated: number; } export declare function createBudget(limits: ResolvedDecompressionLimits): DecompressionBudget; /** * Per-entry inflate cap, accounting for both the absolute per-entry bound and * the ratio-based bound. Returns the smaller of the two — whichever fires * first stops the inflate loop. */ export declare function entryInflateCap(budget: DecompressionBudget, compressedSize: number): number; /** Throw if the declared central-directory totals already exceed the limits. */ export declare function checkDeclaredTotals(budget: DecompressionBudget, declaredEntries: ReadonlyArray<{ path: string; compSize: number; uncompSize: number; }>): void; /** * Record `bytes` against the global budget. Throws when the running total * crosses {@link ResolvedDecompressionLimits.maxTotalUncompressedBytes}. Called * from both sync and streaming inflate code paths. */ export declare function recordInflated(budget: DecompressionBudget, path: string, bytes: number): void; /** Build the message thrown when a single entry exceeds its cap mid-inflate. */ export declare function entryOverflowError(path: string, cap: number): OpenXmlDecompressionBombError;