{"record":{"id":"2793d75e72bb1ffd","repo":"can1357/oh-my-pi","slug":"invalid-cab-archive-zero-length-lzx-block","errorCode":null,"errorMessage":"Invalid CAB archive: zero-length LZX block","messagePattern":"Invalid CAB archive: zero-length LZX block","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/lzx.ts","lineNumber":231,"sourceCode":"\t\t\tthis.#blockRemaining -= produced;\n\t\t}\n\t\tif (this.#blockRemaining === 0 && this.#blockType === 3 && this.#uncompressedPadding) {\n\t\t\treader.readByte();\n\t\t\tthis.#uncompressedPadding = false;\n\t\t}\n\t\treader.alignWord();\n\n\t\tconst translated = this.#translateE8(raw);\n\t\tthis.#frame++;\n\t\treturn translated;\n\t}\n\n\t#readBlockHeader(reader: LzxBitReader): void {\n\t\tif (this.#blockType === 3 && this.#uncompressedPadding) reader.readByte();\n\t\tthis.#uncompressedPadding = false;\n\t\tthis.#blockType = reader.readBits(3);\n\t\tthis.#blockLength = reader.readBits(16) * 256 + reader.readBits(8);\n\t\tif (this.#blockLength === 0) throw new ArchiveError(\"Invalid CAB archive: zero-length LZX block\");\n\t\tthis.#blockRemaining = this.#blockLength;\n\n\t\tif (this.#blockType === 1 || this.#blockType === 2) {\n\t\t\tif (this.#blockType === 2) {\n\t\t\t\tconst alignedLengths = new Uint8Array(8);\n\t\t\t\tfor (let index = 0; index < alignedLengths.byteLength; index++) alignedLengths[index] = reader.readBits(3);\n\t\t\t\tthis.#alignedTable = new LzxHuffmanTable(alignedLengths);\n\t\t\t}\n\t\t\treadCodeLengths(reader, this.#mainLengths, 0, 256);\n\t\t\treadCodeLengths(reader, this.#mainLengths, 256, this.#mainLengths.byteLength);\n\t\t\tthis.#mainTable = new LzxHuffmanTable(this.#mainLengths);\n\t\t\tif (this.#mainLengths[0xe8] !== 0) this.#intelStarted = true;\n\t\t\treadCodeLengths(reader, this.#lengthLengths, 0, this.#lengthLengths.byteLength);\n\t\t\tthis.#lengthTable = new LzxHuffmanTable(this.#lengthLengths, true);\n\t\t\treturn;\n\t\t}\n\t\tif (this.#blockType === 3) {\n\t\t\tthis.#intelStarted = true;","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/lzx.ts#L213-L249","documentation":"When starting a new LZX block, #readBlockHeader reads a 24-bit block length; a length of zero is illegal because every block must produce at least one byte, so the decoder rejects it instead of looping forever on a no-op block. This indicates a corrupt or malformed bitstream.","triggerScenarios":"Decoding a CAB LZX stream whose next block header encodes blockLength = 0 (all 24 length bits zero), typically after bit desync or data truncation.","commonSituations":"Corrupted or truncated downloads, encoders emitting empty blocks, feeding wrong byte offsets so padding bytes are parsed as a block header.","solutions":["Verify and re-download the CAB archive.","Recompress with a standard CAB tool so every block has a non-zero length.","Check frame/block byte boundaries — desync from a prior error can land the reader on padding interpreted as a zero header.","Never continue using an LzxDecoder instance after a thrown ArchiveError; rebuild it from the folder start."],"exampleFix":"// before\ndecoder.decompressFrame(bytes.slice(4), size) // arbitrary skip desyncs the bitstream\n// after\ndecoder.decompressFrame(bytes, size) // feed exact CFDATA block bytes; fresh decoder per folder","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const out = decoder.decompressFrame(bytes, size)\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('zero-length LZX block')) {\n    throw new Error('CAB archive corrupt: zero-length LZX block header')\n  }\n  throw err\n}","preventionTips":["Validate archive integrity before decoding","Do not skip or trim bytes within a frame — bit alignment matters","Restart the folder decode with a fresh LzxDecoder after any ArchiveError"],"tags":["archive","cab","lzx","corruption","block-header"],"backgroundTag":"corrupt-archive-huffman-tree","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}