{"record":{"id":"8d74af00db76928f","repo":"can1357/oh-my-pi","slug":"unsupported-cab-format-version-fixed-25-fixe","errorCode":null,"errorMessage":"Unsupported CAB format version ${fixed[25]}.${fixed[24]} (expected 1.3)","messagePattern":"Unsupported CAB format version (.+?)\\.(.+?) \\(expected 1\\.3\\)","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/cab.ts","lineNumber":259,"sourceCode":"}\n\nasync function readCabArchive(source: ByteSource, options: Parameters<FormatReader>[1]): Promise<ArchiveIndexEntry[]> {\n\tif (source.size < FIXED_HEADER_SIZE) throw new ArchiveError(\"Invalid CAB archive: truncated CFHEADER\");\n\tconst fixed = await readExact(source, 0, FIXED_HEADER_SIZE);\n\tif (!hasSignature(fixed)) throw new ArchiveError(`Invalid CAB archive: expected ${CAB_SIGNATURE} signature`);\n\tif (readUInt32LE(fixed, 4) !== 0 || readUInt32LE(fixed, 12) !== 0 || readUInt32LE(fixed, 20) !== 0) {\n\t\tthrow new ArchiveError(\"Invalid CAB archive: reserved CFHEADER fields must be zero\");\n\t}\n\tconst cabinetSize = readUInt32LE(fixed, 8);\n\tif (cabinetSize < FIXED_HEADER_SIZE || cabinetSize > source.size) {\n\t\tthrow new ArchiveError(\"Invalid CAB archive: declared cabinet size is out of bounds\");\n\t}\n\tconst fileTableOffset = readUInt32LE(fixed, 16);\n\tif (fileTableOffset < FIXED_HEADER_SIZE || fileTableOffset > cabinetSize) {\n\t\tthrow new ArchiveError(\"Invalid CAB archive: CFFILE table offset is out of bounds\");\n\t}\n\tif (fixed[24] !== 3 || fixed[25] !== 1) {\n\t\tthrow new ArchiveError(`Unsupported CAB format version ${fixed[25]}.${fixed[24]} (expected 1.3)`);\n\t}\n\tconst folderCount = readUInt16LE(fixed, 26);\n\tconst fileCount = readUInt16LE(fixed, 28);\n\tconst flags = readUInt16LE(fixed, 30);\n\tif (flags & 0x0003) throw new ArchiveError(\"Unsupported multi-volume CAB archive (previous/next cabinet link)\");\n\tassertEntryCount(folderCount + fileCount, options.limits);\n\tif (folderCount === 0 && fileCount !== 0)\n\t\tthrow new ArchiveError(\"Invalid CAB archive: files exist without a folder\");\n\n\tlet headerReserveSize = 0;\n\tlet folderReserveSize = 0;\n\tlet dataReserveSize = 0;\n\tlet folderTableOffset = FIXED_HEADER_SIZE;\n\tif (flags & 0x0004) {\n\t\tconst reserveHeader = await readExact(source, FIXED_HEADER_SIZE, FIXED_HEADER_SIZE + 4, cabinetSize);\n\t\theaderReserveSize = readUInt16LE(reserveHeader, 0);\n\t\tfolderReserveSize = reserveHeader[2]!;\n\t\tdataReserveSize = reserveHeader[3]!;","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/cab.ts#L241-L277","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Verify the file with cabextract; a genuinely corrupt version field means the archive must be replaced.","If you are generating CAB files, ensure offset 24 is 0x03 (minor version 3) and offset 25 is 0x01 (major version 1).","Check for transfer corruption by comparing checksums against the source of the file.","If a real future CAB version is required, this library does not support it — use a format-specific tool instead."],"exampleFix":"// before (custom writer)\nheader[24] = 0x01; header[25] = 0x03; // wrong order\n// after\nheader[24] = 0x03; header[25] = 0x01; // version 1.3, minor then major","handlingStrategy":"validation","validationCode":"const buf = new Uint8Array(await Bun.file(path).arrayBuffer());\nif (buf[24] !== 3 || buf[25] !== 1) {\n\tthrow new Error(`Unsupported CAB version ${buf[25]}.${buf[24]}; only 1.3 is valid`);\n}","typeGuard":null,"tryCatchPattern":"try {\n\tconst entries = await readCab(source);\n} catch (err) {\n\tif (err instanceof ArchiveError && err.message.startsWith(\"Unsupported CAB format version\")) {\n\t\tthrow new Error(\"This CAB file claims an invalid/unsupported version and is likely corrupt\", { cause: err });\n\t}\n\tthrow err;\n}","preventionTips":["Check header bytes 24-25 equal 0x03,0x01 before parsing untrusted files.","When generating CABs, write minor=3 at offset 24 and major=1 at offset 25.","Use cabextract as a pre-flight validator for archives from unknown origins."],"tags":["archive","cab","unsupported-version","file-format"],"backgroundTag":"unsupported-archive-version","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}