can1357/oh-my-pi · error · ArchiveError

Unsupported CAB format version ${fixed[25]}.${fixed[24]} (ex

Error message

Unsupported CAB format version ${fixed[25]}.${fixed[24]} (expected 1.3)

What it means

CAB stores its format version as major at offset 25 and minor at offset 24. The library only supports version 1.3 (the only version ever defined by the format) and rejects anything else. bytes[24] must be 3 (minor) and bytes[25] must be 1 (major); the message reports the version it found as major.minor.

Source

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

}

async function readCabArchive(source: ByteSource, options: Parameters<FormatReader>[1]): Promise<ArchiveIndexEntry[]> {
	if (source.size < FIXED_HEADER_SIZE) throw new ArchiveError("Invalid CAB archive: truncated CFHEADER");
	const fixed = await readExact(source, 0, FIXED_HEADER_SIZE);
	if (!hasSignature(fixed)) throw new ArchiveError(`Invalid CAB archive: expected ${CAB_SIGNATURE} signature`);
	if (readUInt32LE(fixed, 4) !== 0 || readUInt32LE(fixed, 12) !== 0 || readUInt32LE(fixed, 20) !== 0) {
		throw new ArchiveError("Invalid CAB archive: reserved CFHEADER fields must be zero");
	}
	const cabinetSize = readUInt32LE(fixed, 8);
	if (cabinetSize < FIXED_HEADER_SIZE || cabinetSize > source.size) {
		throw new ArchiveError("Invalid CAB archive: declared cabinet size is out of bounds");
	}
	const fileTableOffset = readUInt32LE(fixed, 16);
	if (fileTableOffset < FIXED_HEADER_SIZE || fileTableOffset > cabinetSize) {
		throw new ArchiveError("Invalid CAB archive: CFFILE table offset is out of bounds");
	}
	if (fixed[24] !== 3 || fixed[25] !== 1) {
		throw new ArchiveError(`Unsupported CAB format version ${fixed[25]}.${fixed[24]} (expected 1.3)`);
	}
	const folderCount = readUInt16LE(fixed, 26);
	const fileCount = readUInt16LE(fixed, 28);
	const flags = readUInt16LE(fixed, 30);
	if (flags & 0x0003) throw new ArchiveError("Unsupported multi-volume CAB archive (previous/next cabinet link)");
	assertEntryCount(folderCount + fileCount, options.limits);
	if (folderCount === 0 && fileCount !== 0)
		throw new ArchiveError("Invalid CAB archive: files exist without a folder");

	let headerReserveSize = 0;
	let folderReserveSize = 0;
	let dataReserveSize = 0;
	let folderTableOffset = FIXED_HEADER_SIZE;
	if (flags & 0x0004) {
		const reserveHeader = await readExact(source, FIXED_HEADER_SIZE, FIXED_HEADER_SIZE + 4, cabinetSize);
		headerReserveSize = readUInt16LE(reserveHeader, 0);
		folderReserveSize = reserveHeader[2]!;
		dataReserveSize = reserveHeader[3]!;

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the file with cabextract; a genuinely corrupt version field means the archive must be replaced.
  2. If you are generating CAB files, ensure offset 24 is 0x03 (minor version 3) and offset 25 is 0x01 (major version 1).
  3. Check for transfer corruption by comparing checksums against the source of the file.
  4. If a real future CAB version is required, this library does not support it — use a format-specific tool instead.

Example fix

// before (custom writer)
header[24] = 0x01; header[25] = 0x03; // wrong order
// after
header[24] = 0x03; header[25] = 0x01; // version 1.3, minor then major
Defensive patterns

Strategy: validation

Validate before calling

const buf = new Uint8Array(await Bun.file(path).arrayBuffer());
if (buf[24] !== 3 || buf[25] !== 1) {
	throw new Error(`Unsupported CAB version ${buf[25]}.${buf[24]}; only 1.3 is valid`);
}

Try / catch

try {
	const entries = await readCab(source);
} catch (err) {
	if (err instanceof ArchiveError && err.message.startsWith("Unsupported CAB format version")) {
		throw new Error("This CAB file claims an invalid/unsupported version and is likely corrupt", { cause: err });
	}
	throw err;
}

Prevention

When it happens

Trigger: Calling readCab() on a signed CAB whose versionReserved fields (offsets 24-25) are not 0x03,0x01 — e.g. bytes overwritten by corruption or a fictional future version number in a crafted file.

Common situations: Fuzzed or malicious archives claiming version 2.x or garbage versions, corrupted files where the version bytes were clobbered, or synthetic test files written by hand-rolled encoders that mis-ordered the version fields (writing 1.3 as major at offset 24).

Related errors


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