can1357/oh-my-pi · error · ArchiveError
Invalid ${label} command Huffman table size
Error message
Invalid ${label} command Huffman table size What it means
readCommandTree() reads a 9-bit encodedCount for the command table (510 symbols for LH5/LH6, larger spaces handled by the caller). A count above symbolCount cannot occur in a valid stream, so the library throws ArchiveError before allocating/reading the length array. This protects against corrupt headers and prevents out-of-range table parsing.
Source
Thrown at packages/utils/src/ar/lzh.ts:165
if (encodedCount > symbolCount) throw new ArchiveError(`Invalid ${label} temporary Huffman table size`);
const lengths = new Uint8Array(symbolCount);
let index = 0;
while (index < encodedCount) {
lengths[index++] = readCodeLength(reader, label);
if (index === 3) {
const skipped = reader.read(2);
if (index + skipped > encodedCount) throw new ArchiveError(`Invalid ${label} temporary Huffman table`);
index += skipped;
}
}
return CanonicalHuffman.build(lengths, symbolCount, label);
}
function readCommandTree(reader: MsbBitReader, temporary: CanonicalHuffman, label: string): CanonicalHuffman {
const symbolCount = 510;
const encodedCount = reader.read(9);
if (encodedCount === 0) return CanonicalHuffman.single(reader.read(9), symbolCount, label);
if (encodedCount > symbolCount) throw new ArchiveError(`Invalid ${label} command Huffman table size`);
const lengths = new Uint8Array(symbolCount);
let index = 0;
while (index < encodedCount) {
const code = temporary.decode(reader);
if (code <= 2) {
const skipped = code === 0 ? 1 : code === 1 ? reader.read(4) + 3 : reader.read(9) + 20;
if (index + skipped > encodedCount) throw new ArchiveError(`Invalid ${label} command Huffman table`);
index += skipped;
} else {
lengths[index++] = code - 2;
}
}
return CanonicalHuffman.build(lengths, symbolCount, label);
}
function readPositionTree(
reader: MsbBitReader,
positionBits: number,View on GitHub (pinned to 9690622007)
Solutions
- Check the archive's method byte and use the matching table size / decompressor path
- Recompute the compressed-data start offset (header parse, extended-header skip) before decompressLhStatic
- Validate the file externally and restore a clean copy if checks fail
- Catch ArchiveError and report a corrupt or unsupported archive; retrying is pointless
Example fix
// before: single fixed-size path for all variants
const commandTree = readCommandTree(reader, tempTree, 'command');
// after: route by declared method
if (method === 'LH7') { /* 510+ symbol path */ } else { const commandTree = readCommandTree(reader, tempTree, 'command'); } Defensive patterns
Strategy: try-catch
Validate before calling
// Verify offsets and method before decompressing:
if (!isSupportedLhMethod(method)) throw new Error(`unsupported method: ${method}`);
if (dataStart + declaredCompressedSize > data.length) throw new Error('truncated archive'); Type guard
function isSupportedLhMethod(method: string): boolean {
return ['LH4', 'LH5', 'LH6', 'LH7'].includes(method);
} Try / catch
try {
const out = decompressLhStatic(data.subarray(dataStart), originalSize);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('table size')) {
throw new Error('command table header corrupt or LH-variant mismatch');
}
throw err;
} Prevention
- Route LH7 (larger symbol spaces) to the correct decompressor path
- Parse extended LHA headers fully so the data offset is exact
- Validate archive integrity externally before batch extraction
- Do not retry decoding after a table-size rejection — the input is corrupt
When it happens
Trigger: decompressLhStatic on a stream whose 9-bit command count field is corrupted or misread — e.g. parsing an LH7 block with an LH5-sized reader, byte-offset errors from a bad LHA header, or fuzzed inputs with counts > 510.
Common situations: Truncated or damaged .lzh files, variant mismatches (LH4/LH5/LH6/LH7 confusion), misparsed extended headers shifting the data start, fuzzing.
Related errors
- Invalid ${label} temporary Huffman table size
- Invalid ${label} Huffman table: oversubscribed codes
- Invalid ${label} Huffman table: incomplete codes
- Invalid ${label} Huffman table: prefix collision
- Invalid ${label} Huffman table: duplicate code
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/f1cb822388635af1.
Report an issue: GitHub.