{"record":{"id":"2e446aa2a46dbe69","repo":"can1357/oh-my-pi","slug":"lzh-member-memberpath-extracted-to-an-unexpec","errorCode":null,"errorMessage":"LZH member '${memberPath}' extracted to an unexpected size","messagePattern":"LZH member '(.+?)' extracted to an unexpected size","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/lzh.ts","lineNumber":442,"sourceCode":"\t\t\tcase \"-lh5-\":\n\t\t\t\toutput = decompressLhStatic(packed, size, 1 << 13, 4, 14, \"LZH -lh5-\");\n\t\t\t\tbreak;\n\t\t\tcase \"-lh6-\":\n\t\t\t\toutput = decompressLhStatic(packed, size, 1 << 15, 5, 16, \"LZH -lh6-\");\n\t\t\t\tbreak;\n\t\t\tcase \"-lh7-\":\n\t\t\t\toutput = decompressLhStatic(packed, size, 1 << 16, 5, 17, \"LZH -lh7-\");\n\t\t\t\tbreak;\n\t\t\tcase \"-lzs-\":\n\t\t\t\toutput = decompressLzs(packed, size);\n\t\t\t\tbreak;\n\t\t\tcase \"-lh1-\":\n\t\t\t\tthrow new ArchiveError(`LZH member '${memberPath}' uses unsupported dynamic-Huffman method -lh1-`);\n\t\t\tdefault:\n\t\t\t\tthrow new ArchiveError(`LZH member '${memberPath}' uses unsupported compression method ${this.#method}`);\n\t\t}\n\t\tif (output.byteLength !== size)\n\t\t\tthrow new ArchiveError(`LZH member '${memberPath}' extracted to an unexpected size`);\n\t\tif (crc16Arc(output) !== this.#crc)\n\t\t\tthrow new ArchiveError(`LZH member '${memberPath}' failed CRC-16 verification`);\n\t\treturn output;\n\t}\n}\n\ninterface ParsedLzhHeader {\n\tmethod: string;\n\tpackedSize: number;\n\tsize: number;\n\tdataStart: number;\n\tnextOffset: number;\n\tcrc: number;\n\tpath?: string;\n\tmtimeMs?: number;\n\tmode?: number;\n}\n","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/lzh.ts#L424-L460","documentation":"After decompression the reader verifies that the decoder produced exactly the declared uncompressed size. If a compression method's output length differs from the size in the header (or from the 0x42 64-bit-size override), the archive is internally inconsistent and the member is rejected before CRC verification.","triggerScenarios":"Extracting an LZH member where the compressed stream decompresses to fewer or more bytes than the declared size — corrupt compressed data, wrong size fields (header or type-0x42 extended header), or a decoder/method mismatch from a corrupted method string.","commonSituations":"Bit-rotted or truncated compressed data; size fields edited by faulty tooling; archives that fail CRC anyway due to deeper corruption.","solutions":["Re-obtain the archive — a decompressed-size mismatch indicates data or header corruption","Run the archive through an external extractor to identify the damaged member, then repack only the healthy members","Compare the file against its original checksum to confirm transfer integrity and re-download if mismatched","If you write LZH archives, ensure the size field equals the exact uncompressed byte count you feed the compressor"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"null","tryCatchPattern":"try {\n\tconst data = await member.read();\n} catch (err) {\n\tif (err instanceof ArchiveError && err.message.includes(\"extracted to an unexpected size\")) {\n\t\t// decompressed output disagrees with header size — treat as corrupt member\n\t}\n\tthrow err;\n}","preventionTips":["Verify archive checksums at rest and after transfer","Repack archives whose members consistently fail size/CRC verification","Avoid editing size fields (including 0x42 64-bit headers) by hand"],"tags":["archive","lzh","size-mismatch","corruption"],"backgroundTag":"archive-size-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}