{"record":{"id":"184a111c968d7cff","repo":"can1357/oh-my-pi","slug":"invalid-lzh-level-1-packed-size","errorCode":null,"errorMessage":"Invalid LZH level-1 packed size","messagePattern":"Invalid LZH level-1 packed size","errorType":"validation","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/lzh.ts","lineNumber":527,"sourceCode":"\t\t\t\tif (extensionSize < 3) throw new ArchiveError(\"Invalid LZH extended header size\");\n\t\t\t\tassertRange(bytes, cursor, cursor + extensionSize, \"extended header\");\n\t\t\t\ttotalExtensionSize += extensionSize;\n\t\t\t\tassertIndexSize(headerLength + 2 + totalExtensionSize, options.limits, \"header metadata\");\n\t\t\t\tif (++extensionCount > 65_535) throw new ArchiveError(\"Invalid LZH archive: too many extended headers\");\n\t\t\t\tconst type = bytes[cursor]!;\n\t\t\t\tconst dataEnd = cursor + extensionSize - 2;\n\t\t\t\tconst data = bytes.subarray(cursor + 1, dataEnd);\n\t\t\t\tif (type === 0x01 || type === 0x02 || type === 0x44 || type === 0x45) {\n\t\t\t\t\tassertArchivePathBytes(data.byteLength, \"member path\", options.limits.maxPathBytes);\n\t\t\t\t}\n\t\t\t\tprocessExtendedHeader(type, data, cursor + 1, fields);\n\t\t\t\tconst currentSize = extensionSize;\n\t\t\t\textensionSize = u16(bytes, dataEnd);\n\t\t\t\tcursor += currentSize;\n\t\t\t}\n\t\t\tdataStart = baseEnd + totalExtensionSize;\n\t\t\tpackedSize = fields.packedSize ?? packedSize - totalExtensionSize;\n\t\t\tif (packedSize < 0) throw new ArchiveError(\"Invalid LZH level-1 packed size\");\n\t\t}\n\t} else {\n\t\tconst headerLength = u16(bytes, offset);\n\t\tif (headerLength < 26) throw new ArchiveError(\"Invalid LZH level-2 header size\");\n\t\tconst headerEnd = offset + headerLength;\n\t\tassertRange(bytes, offset, headerEnd, \"header\");\n\t\tcrc = u16(bytes, offset + 21);\n\t\tosId = bytes[offset + 23]!;\n\t\tmtimeMs = u32(bytes, offset + 15) * 1000;\n\t\tlet cursor = offset + 24;\n\t\tlet extensionCount = 0;\n\t\twhile (cursor + 2 <= headerEnd) {\n\t\t\tconst extensionSize = u16(bytes, cursor);\n\t\t\tif (extensionSize === 0) {\n\t\t\t\tcursor += 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (extensionSize < 3 || cursor + extensionSize > headerEnd)","sourceCodeStart":509,"sourceCodeEnd":545,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/lzh.ts#L509-L545","documentation":"Thrown for a level-1 LZH member when, after subtracting the total extended-header bytes (or taking the header-declared packed size), the remaining packed size is negative. The member's compressed payload cannot have negative length, so the header fields are inconsistent.","triggerScenarios":"A level-1 header where the recorded packed size is smaller than the sum of its extended headers, or where the packedSize extension field itself is malformed.","commonSituations":"Corrupted or truncated archives, non-conforming writers that misaccount extension sizes, fuzzed inputs.","solutions":["Replace the archive with an intact copy","Repack with a standard LHA tool","If you write LZH files, ensure packedSize accounting includes/excludes extended headers per the level-1 spec"],"exampleFix":"null","handlingStrategy":"validation","validationCode":"if (u32(bytes, 7) > bytes.byteLength) throw new Error('packed size exceeds file');","typeGuard":null,"tryCatchPattern":"try { parse(); } catch (err) { if (err instanceof ArchiveError && err.message.includes('packed size')) reject(err); else throw err; }","preventionTips":["Sanity-check header sizes against file size before parse","Verify archive integrity on ingest"],"tags":["archive","lzh","level-1","size","malformed"],"backgroundTag":"corrupt-archive-header","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}