{"record":{"id":"749d41aa9d6744a9","repo":"can1357/oh-my-pi","slug":"unsupported-cab-compression-method-quantum-level","errorCode":null,"errorMessage":"Unsupported CAB compression method: Quantum (level ${description.parameter})","messagePattern":"Unsupported CAB compression method: Quantum \\(level (.+?)\\)","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/cab.ts","lineNumber":130,"sourceCode":"\treadonly #limits: ArchiveLimits;\n\t#decoded?: Promise<Uint8Array>;\n\n\tconstructor(source: ByteSource, description: CabFolderDescription, dataReserveSize: number, limits: ArchiveLimits) {\n\t\tthis.#source = source;\n\t\tthis.#description = description;\n\t\tthis.#dataReserveSize = dataReserveSize;\n\t\tthis.#limits = limits;\n\t}\n\n\treadAll(): Promise<Uint8Array> {\n\t\tthis.#decoded ??= this.#decode();\n\t\treturn this.#decoded;\n\t}\n\n\tasync #decode(): Promise<Uint8Array> {\n\t\tconst description = this.#description;\n\t\tif (description.method === 2) {\n\t\t\tthrow new ArchiveError(`Unsupported CAB compression method: Quantum (level ${description.parameter})`);\n\t\t}\n\t\tif (description.method > 3) {\n\t\t\tthrow new ArchiveError(`Unsupported CAB compression method: ${description.method}`);\n\t\t}\n\t\tif (description.method === 3 && (description.parameter < 15 || description.parameter > 21)) {\n\t\t\tthrow new ArchiveError(`Unsupported CAB LZX window size: ${description.parameter} bits (expected 15-21)`);\n\t\t}\n\n\t\tconst compressedSize = description.dataEnd - description.dataStart;\n\t\tassertInMemorySize(compressedSize, this.#limits);\n\t\tconst bytes = await readExact(this.#source, description.dataStart, description.dataEnd);\n\t\tlet position = 0;\n\t\tlet outputSize = 0;\n\t\tfor (let block = 0; block < description.blockCount; block++) {\n\t\t\tif (position + DATA_BLOCK_SIZE + this.#dataReserveSize > bytes.byteLength) {\n\t\t\t\tthrow new ArchiveError(\"Invalid CAB archive: truncated CFDATA header\");\n\t\t\t}\n\t\t\tconst compressed = readUInt16LE(bytes, position + 4);","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/cab.ts#L112-L148","documentation":"The reader supports CAB compression methods None(0), Deflate(1), and LZX(3), but Quantum (method 2) has no decoder and is rejected explicitly, including its window parameter. Quantum is an obsolete IBM/MS compression scheme rarely needed today. This throws before any data is read, as soon as #decode inspects the folder description.","triggerScenarios":"Calling readAll() (directly or via the public extract/read APIs) on a CAB whose CFFOLDER typeCompress field indicates method 2 (Quantum), regardless of the quantum level in the parameter field.","commonSituations":"Old CABs produced by MS-DOS-era tools (Diamond 1.x era, early InstallShield packages) that defaulted to Quantum; legacy software distribution archives from the 1990s; archives re-compressed with Quantum to shrink floppy-sized media.","solutions":["Re-compress the archive with a supported method: unpack with cabextract (it supports Quantum via libmspack) and repack with Deflate or LZX, e.g. `lcab -m deflate` or plain `lcab` (store).","Extract contents with `cabextract file.cab` outside this library and consume the extracted files instead.","If the archive is from an installer, use a dedicated installer-extraction tool (innoextract, 7z) to obtain the payload.","Check whether the CAB-creating tool has an option to use MSZIP/Deflate instead of Quantum and re-export.","If you must read Quantum in-process, add/enable a Quantum decoder or find a JS Quantum implementation and contribute it as method 2 support."],"exampleFix":"// before: Quantum CAB throws in readAll\nawait openCab('legacy.cab').then(r => r.readAll()); // Unsupported ... Quantum (level 2)\n// after: convert with cabextract + lcab\ncabextract legacy.cab -d out/\nlcab out/ converted.cab\nawait openCab('converted.cab').then(r => r.readAll());","handlingStrategy":"validation","validationCode":"// Peek the folder compression method (typeCompress low bits) before full read\nconst method = readFolderCompressionMethod(cabBytes); // your own header peek\nif (method === 2) throw new Error('CAB uses unsupported Quantum compression — convert with cabextract/lcab first');","typeGuard":"function isSupportedCabMethod(m: number): boolean {\n  return m === 0 || m === 1 || m === 3;\n}","tryCatchPattern":"try {\n  return await readCabArchive(bytes);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('Quantum')) {\n    throw new Error('Convert this legacy Quantum CAB to MSZIP/LZX before in-process reading');\n  }\n  throw err;\n}","preventionTips":["Convert legacy 1990s CABs to Deflate/MSZIP once, upstream of your pipeline.","When creating CABs, explicitly choose MSZIP or LZX — never Quantum.","Detect Quantum at ingestion (method byte 2) and route to an external converter.","Keep cabextract or 7z available as an escape hatch for legacy formats."],"tags":["compression","quantum","unsupported","cab"],"backgroundTag":"unsupported-compression-method","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}