can1357/oh-my-pi · error · ArchiveError
Invalid CAB archive: CFFOLDER table is out of bounds
Error message
Invalid CAB archive: CFFOLDER table is out of bounds
What it means
The library computes where the CFFOLDER table ends: folderTableOffset (fixed header + optional reserve) + folderCount * folderRecordSize (8 + folder reserve). It requires this end to be a safe integer, to fit within the declared cabinet size, and not to run past the CFFILE table offset. Otherwise the folder table would overlap other structures or read past the file, so it throws.
Source
Thrown at packages/utils/src/ar/cab.ts:285
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]!;
if (headerReserveSize > 60_000)
throw new ArchiveError("Invalid CAB archive: CFHEADER reserve area exceeds 60000 bytes");
folderTableOffset += 4 + headerReserveSize;
}
const folderRecordSize = 8 + folderReserveSize;
const folderTableEnd = folderTableOffset + folderCount * folderRecordSize;
if (!Number.isSafeInteger(folderTableEnd) || folderTableEnd > cabinetSize || folderTableEnd > fileTableOffset) {
throw new ArchiveError("Invalid CAB archive: CFFOLDER table is out of bounds");
}
assertIndexSize(folderTableEnd, options.limits, "CAB header");
const header = await readExact(source, 0, folderTableEnd, cabinetSize);
const descriptions: CabFolderDescription[] = [];
for (let index = 0; index < folderCount; index++) {
const offset = folderTableOffset + index * folderRecordSize;
const type = readUInt16LE(header, offset + 6);
descriptions.push({
dataStart: readUInt32LE(header, offset),
dataEnd: cabinetSize,
blockCount: readUInt16LE(header, offset + 4),
method: type & 0x000f,
parameter: type >>> 8,
requiredSize: 0,
});
}
for (const description of descriptions) {
if (description.dataStart < folderTableEnd || description.dataStart > cabinetSize) {View on GitHub (pinned to 9690622007)
Solutions
- Validate the cabinet with cabextract/7-Zip to confirm the header layout is inconsistent, then re-obtain the file.
- Check cFolders (offset 26), cbCFHeader reserve (offset 36 area) and coffFiles (offset 16) against each other with a hex dump.
- If you write CAB files, compute the folder-table end before placing the CFFILE table and ensure it fits inside cbCabinet.
- Reduce folder counts in generated archives; enormous folder counts usually indicate a writer bug or an attack input.
Defensive patterns
Strategy: validation
Validate before calling
const buf = new Uint8Array(await Bun.file(path).arrayBuffer());
const u32 = (o: number) => (buf[o]! | (buf[o + 1]! << 8) | (buf[o + 2]! << 16) | (buf[o + 3]! << 24)) >>> 0;
const u16 = (o: number) => buf[o]! | (buf[o + 1]! << 8);
const cbCabinet = u32(8), coffFiles = u32(16);
const folderCount = u16(26);
const flags = u16(30);
let folderTableOffset = 36;
if (flags & 0x0004) folderTableOffset += 4 + u16(36);
const end = folderTableOffset + folderCount * 8; // assumes no folder reserve
if (end > cbCabinet || end > coffFiles) throw new Error("CAB folder table would overflow the cabinet"); Try / catch
try {
const entries = await readCab(source);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("CFFOLDER table is out of bounds")) {
logger.warn("Skipping CAB with inconsistent folder table", { path });
return null;
}
throw err;
} Prevention
- Compute folder-table extent against cbCabinet and coffFiles before parsing untrusted files.
- Reject archives with implausible folder counts early.
- Validate with an external tool when the archive origin is unknown.
When it happens
Trigger: Calling readCab() on a CAB whose folder count, folder reserve size, header reserve size, or offsets are inconsistent — e.g. folderCount * (8 + folderReserveSize) overflows to a non-safe integer, or the table extends beyond cbCabinet or coffFiles.
Common situations: Fuzzed archives with huge folder counts, corrupted files where the folder count or reserve fields were altered, and buggy writers that place the CFFILE table before the folder table ends.
Related errors
- Invalid CAB archive: CFFILE table offset 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/4d4cba45abe40961.
Report an issue: GitHub.