can1357/oh-my-pi · error · ArchiveError
Invalid CAB archive: CFFILE table offset is out of bounds
Error message
Invalid CAB archive: CFFILE table offset is out of bounds
What it means
The CFHEADER's coffFiles field (offset 16) points to the start of the CFFILE table. The library requires it to fall within the cabinet: at or after the fixed header and at or before the declared cabinet size. An out-of-range offset means the header's internal layout is inconsistent.
Source
Thrown at packages/utils/src/ar/cab.ts:256
}
return folder.slice(this.#offset, end);
}
}
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);View on GitHub (pinned to 9690622007)
Solutions
- Treat the archive as corrupt and obtain a fresh copy; the library will not follow an untrusted offset.
- Hex-dump bytes 16-19 and 8-11 and verify coffFiles lies between 36 and cbCabinet.
- If a custom packer produced the file, fix its coffFiles computation to point at the first CFFILE entry.
- Validate the cabinet with cabextract or 7-Zip to confirm the header is genuinely inconsistent.
Defensive patterns
Strategy: validation
Validate before calling
const buf = new Uint8Array(await Bun.file(path).arrayBuffer());
const coffFiles = (buf[16] | (buf[17]! << 8) | (buf[18]! << 16) | (buf[19]! << 24)) >>> 0;
const cbCabinet = (buf[8] | (buf[9]! << 8) | (buf[10]! << 16) | (buf[11]! << 24)) >>> 0;
if (coffFiles < 36 || coffFiles > cbCabinet) throw new Error("CAB CFFILE offset out of range; archive is corrupt"); Try / catch
try {
const entries = await readCab(source);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("CFFILE table offset is out of bounds")) {
logger.warn("Skipping CAB with inconsistent file-table offset", { path });
return null;
}
throw err;
} Prevention
- Validate archives from untrusted sources with an external tool before parsing.
- If writing CABs, verify coffFiles points at the first CFFILE entry.
- Check transfer checksums; byte corruption commonly lands in header fields.
When it happens
Trigger: Calling readCab() on a signed CAB whose first-file-table offset (bytes 16-19) is smaller than 36 or greater than cbCabinet — produced by corruption, a faulty writer, or deliberate malformation.
Common situations: Cabinets produced by non-conforming or buggy custom packers, files damaged by byte-level corruption, and hand-crafted or fuzzed inputs where the file-table pointer was miswritten.
Related errors
- Invalid CAB archive: CFFOLDER table is out of bounds
- Invalid CAB archive: CFFOLDER data offset is out of bounds
- Invalid CAB archive: reserved CFHEADER fields must be zero
- Invalid CAB archive: declared cabinet size is out of bounds
- Invalid CAB archive: files exist without a folder
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/9a531398dfa6686e.
Report an issue: GitHub.