{"record":{"id":"188e49132e12dead","repo":"can1357/oh-my-pi","slug":"unsupported-cab-lzx-window-size-description-par","errorCode":null,"errorMessage":"Unsupported CAB LZX window size: ${description.parameter} bits (expected 15-21)","messagePattern":"Unsupported CAB LZX window size: (.+?) bits \\(expected 15-21\\)","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/cab.ts","lineNumber":136,"sourceCode":"\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);\n\t\t\tconst uncompressed = readUInt16LE(bytes, position + 6);\n\t\t\tif (uncompressed === 0) throw new ArchiveError(\"Unsupported multi-volume CAB archive: split CFDATA block\");\n\t\t\tif (uncompressed > MAX_DATA_OUTPUT) {\n\t\t\t\tthrow new ArchiveError(`Invalid CAB archive: CFDATA expands to ${uncompressed} bytes (maximum 32768)`);\n\t\t\t}\n\t\t\tconst payloadStart = position + DATA_BLOCK_SIZE + this.#dataReserveSize;","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/cab.ts#L118-L154","documentation":"LZX (method 3) is supported only with window sizes of 15 to 21 bits, matching the CAB spec's legal LZX window range. A CFFOLDER whose data block's parameter (window bits) falls outside 15–21 is rejected before decoding. This protects the decoder from allocating absurd or invalid windows.","triggerScenarios":"readAll() on a CAB whose LZX folder declares a window size parameter < 15 or > 21 in its CFDATA/lzx parameter field.","commonSituations":"Corrupted typeCompress/parameter bytes in the folder header; nonstandard LZX writers using out-of-spec window bits; crafted archives probing for decoder bugs; tools that stored a quantum-level value in the LZX parameter field by mistake.","solutions":["Re-pack the archive with standard LZX settings (window 15–21 bits) or fall back to Deflate: recreate with lcab/MSZIP.","Confirm with `cabextract -t file.cab` whether cabextract can read it — if yes, the file is fine but out-of-spec for this library; extract externally and repackage.","Hex-dump the CFFOLDER to verify the parameter byte; a single flipped bit implies corruption — re-transfer.","If producing CABs yourself, ensure your LZX compressor is configured for window ≤ 2^21 bytes.","As an escape hatch, extract with 7z/cabextract and process the plain files instead of the CAB in-process."],"exampleFix":"// before: out-of-spec LZX window\nawait openCab('odd.cab').then(r => r.readAll()); // Unsupported CAB LZX window size: 30 bits\n// after: re-pack with default settings\nlcab out/ repacked.cab\nawait openCab('repacked.cab').then(r => r.readAll());","handlingStrategy":"validation","validationCode":"const { method, parameter } = readFolderCompression(cabBytes);\nif (method === 3 && (parameter < 15 || parameter > 21))\n  throw new Error(`LZX window ${parameter} bits is out of spec (15-21) — re-pack the CAB`);","typeGuard":"function isValidLzxWindow(p: number): boolean {\n  return Number.isInteger(p) && p >= 15 && p <= 21;\n}","tryCatchPattern":"try {\n  return await readCabArchive(bytes);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('LZX window size')) {\n    throw new Error('CAB uses an out-of-spec LZX window — re-pack or extract with cabextract');\n  }\n  throw err;\n}","preventionTips":["Configure LZX compressors to standard windows (≤ 2^21).","Sanity-check the folder parameter byte when archives come from unusual tools.","Fall back to MSZIP/Deflate when maximum compatibility matters.","Verify odd CABs with cabextract -t to separate corruption from nonstandard encoding."],"tags":["compression","lzx","cab","validation"],"backgroundTag":"unsupported-compression-method","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}