{"record":{"id":"5b56b1b6780a5664","repo":"can1357/oh-my-pi","slug":"invalid-cab-archive-lzx-match-crosses-a-frame-or","errorCode":null,"errorMessage":"Invalid CAB archive: LZX match crosses a frame or block boundary","messagePattern":"Invalid CAB archive: LZX match crosses a frame or block boundary","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/lzx.ts","lineNumber":285,"sourceCode":"\t\t}\n\t\tif (!this.#mainTable || !this.#lengthTable)\n\t\t\tthrow new ArchiveError(\"Invalid CAB archive: missing LZX decode trees\");\n\n\t\tlet produced = 0;\n\t\twhile (produced < count) {\n\t\t\tconst element = this.#mainTable.decode(reader);\n\t\t\tif (element < 256) {\n\t\t\t\tthis.#writeByte(element, output, outputStart + produced);\n\t\t\t\tproduced++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst match = element - 256;\n\t\t\tlet matchLength = match & NUM_PRIMARY_LENGTHS;\n\t\t\tif (matchLength === NUM_PRIMARY_LENGTHS) matchLength += this.#lengthTable.decode(reader);\n\t\t\tmatchLength += MIN_MATCH;\n\t\t\tif (matchLength > count - produced || matchLength > this.#blockRemaining - produced) {\n\t\t\t\tthrow new ArchiveError(\"Invalid CAB archive: LZX match crosses a frame or block boundary\");\n\t\t\t}\n\n\t\t\tconst slot = match >>> 3;\n\t\t\tlet matchOffset: number;\n\t\t\tif (slot === 0) {\n\t\t\t\tmatchOffset = this.#r0;\n\t\t\t} else if (slot === 1) {\n\t\t\t\tmatchOffset = this.#r1;\n\t\t\t\tthis.#r1 = this.#r0;\n\t\t\t\tthis.#r0 = matchOffset;\n\t\t\t} else if (slot === 2) {\n\t\t\t\tmatchOffset = this.#r2;\n\t\t\t\tthis.#r2 = this.#r0;\n\t\t\t\tthis.#r0 = matchOffset;\n\t\t\t} else {\n\t\t\t\tif (slot >= this.#positionBase.byteLength)\n\t\t\t\t\tthrow new ArchiveError(\"Invalid CAB archive: LZX position slot is out of range\");\n\t\t\t\tconst extra = this.#extraBits[slot]!;","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/lzx.ts#L267-L303","documentation":"A decoded LZX match would produce more bytes than remain in the current block or frame. LZX never allows matches to span block/frame boundaries, so such a match proves the bitstream is corrupt.","triggerScenarios":"decompressFrame -> #decodeRun decodes a match whose matchLength exceeds the requested count or the block's remaining byte budget (#blockRemaining).","commonSituations":"Corrupted CAB data, bit-reader desync from earlier errors, fuzzed archives.","solutions":["Verify archive integrity (CRC/checksum on the CAB).","Re-extract the file; if reproducible, the file is corrupt at the source.","Stop decoding this stream — recovery mid-frame is not possible."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const out = decompressFrame(frame);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"crosses a frame or block boundary\")) {\n    // corrupt stream — abort extraction of this folder\n  } else throw err;\n}","preventionTips":["Abort on the first ArchiveError — LZX cannot resync mid-frame","Pre-verify CAB checksums","Use the whole compressed data payload, not a partial slice"],"tags":["archive","cab","lzx","corrupt-data"],"backgroundTag":"corrupt-archive-data","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}