can1357/oh-my-pi · error · ArchiveError

Unsupported CAB compression method: ${description.method}

Error message

Unsupported CAB compression method: ${description.method}

What it means

Any CFFOLDER compression method value greater than 3 is unknown to this library (known: 0=none, 1=deflate, 2=quantum, 3=LZX), so #decode refuses it rather than guessing. This usually means the archive is corrupt or uses a proprietary/undocumented method code. The raw method number is included in the message for diagnosis.

Source

Thrown at packages/utils/src/ar/cab.ts:133

	constructor(source: ByteSource, description: CabFolderDescription, dataReserveSize: number, limits: ArchiveLimits) {
		this.#source = source;
		this.#description = description;
		this.#dataReserveSize = dataReserveSize;
		this.#limits = limits;
	}

	readAll(): Promise<Uint8Array> {
		this.#decoded ??= this.#decode();
		return this.#decoded;
	}

	async #decode(): Promise<Uint8Array> {
		const description = this.#description;
		if (description.method === 2) {
			throw new ArchiveError(`Unsupported CAB compression method: Quantum (level ${description.parameter})`);
		}
		if (description.method > 3) {
			throw new ArchiveError(`Unsupported CAB compression method: ${description.method}`);
		}
		if (description.method === 3 && (description.parameter < 15 || description.parameter > 21)) {
			throw new ArchiveError(`Unsupported CAB LZX window size: ${description.parameter} bits (expected 15-21)`);
		}

		const compressedSize = description.dataEnd - description.dataStart;
		assertInMemorySize(compressedSize, this.#limits);
		const bytes = await readExact(this.#source, description.dataStart, description.dataEnd);
		let position = 0;
		let outputSize = 0;
		for (let block = 0; block < description.blockCount; block++) {
			if (position + DATA_BLOCK_SIZE + this.#dataReserveSize > bytes.byteLength) {
				throw new ArchiveError("Invalid CAB archive: truncated CFDATA header");
			}
			const compressed = readUInt16LE(bytes, position + 4);
			const uncompressed = readUInt16LE(bytes, position + 6);
			if (uncompressed === 0) throw new ArchiveError("Unsupported multi-volume CAB archive: split CFDATA block");
			if (uncompressed > MAX_DATA_OUTPUT) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Log the reported method number and check it against the CAB spec; if it is far beyond 3, suspect corruption — re-download/re-copy the archive.
  2. Validate the archive with `cabextract -t file.cab` to distinguish real unsupported methods from header corruption.
  3. Re-create the CAB with a standard tool using Deflate (method 1) or LZX (method 3).
  4. If the input is user-supplied, add an upfront signature/structure sanity check and reject such files with a clear message before invoking readAll().
  5. If the method is genuinely needed, extend the decoder with a new branch (as done for LZX) rather than letting it fall into this error.

Example fix

// before: trusting arbitrary uploaded .cab files
await readCabArchive(userUpload); // Unsupported CAB compression method: 17
// after: pre-validate structure with an independent tool or reject early
if (!looksLikeValidCab(await Bun.file(uploadPath).arrayBuffer()))
  throw new Error('Not a structurally valid CAB file');
await readCabArchive(userUpload);
Defensive patterns

Strategy: validation

Validate before calling

const method = readFolderCompressionMethod(cabBytes);
if (method === undefined || method > 3)
  throw new Error(`CAB folder has unknown compression method ${method} — file is corrupt or nonstandard`);

Type guard

function isKnownCabMethod(m: number | undefined): m is 0 | 1 | 2 | 3 {
  return m !== undefined && m >= 0 && m <= 3;
}

Try / catch

try {
  return await readCabArchive(bytes);
} catch (err) {
  if (err instanceof ArchiveError && /compression method: \d+$/.test(err.message)) {
    throw new Error('Unknown CAB compression method — verify the archive is not corrupted');
  }
  throw err;
}

Prevention

When it happens

Trigger: readAll() on a CAB whose folder typeCompress field contains a value > 3 — from corruption, a maliciously crafted file, or a nonstandard producer writing custom method codes.

Common situations: Hand-crafted or fuzzed CAB inputs; corrupted headers where adjacent bytes bled into typeCompress; proprietary archivers that abused reserved method fields; wrong endianness assumptions in files produced by buggy tools.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/06e06d29e06d8e07. Report an issue: GitHub.