can1357/oh-my-pi · error · ArchiveError
Invalid ${label} temporary Huffman table
Error message
Invalid ${label} temporary Huffman table What it means
While reading the temporary table's lengths, after every 3 lengths the format encodes a 2-bit skip count. If the skip would advance the index past the declared encodedCount, the stream is internally inconsistent (declares more symbols than it provides room for), so readTemporaryTree() throws ArchiveError instead of building an invalid table.
Source
Thrown at packages/utils/src/ar/lzh.ts:154
length++;
if (length > 16) throw new ArchiveError(`Invalid ${label} Huffman table: code is too long`);
}
}
return length;
}
function readTemporaryTree(reader: MsbBitReader, label: string): CanonicalHuffman {
const symbolCount = 19;
const encodedCount = reader.read(5);
if (encodedCount === 0) return CanonicalHuffman.single(reader.read(5), symbolCount, label);
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`);View on GitHub (pinned to 9690622007)
Solutions
- Validate the archive externally (unlha -t / CRC) and re-download if it fails
- Confirm the reader position: any earlier table-field misparse shifts all subsequent bits
- If generating archives, emit skip counts consistent with the declared encodedCount
- Catch ArchiveError and treat the file as corrupt
Defensive patterns
Strategy: try-catch
Try / catch
try {
const out = decompressLhStatic(data, size);
} catch (err) {
if (err instanceof ArchiveError) {
return { ok: false, reason: 'corrupt-temporary-table' };
}
throw err;
} Prevention
- Check archive CRC before extraction
- Fix any earlier misparse — skip-field errors usually stem from a shifted bit position
- Ensure encoders emit skip counts consistent with encodedCount
- Fail fast; corrupted tables never self-heal on retry
When it happens
Trigger: Corrupted 2-bit skip fields in the temporary-table section (values pushing index beyond encodedCount), bit misalignment from an earlier misparse, or hand-crafted/fuzzed table bytes.
Common situations: Damaged archives, wrong-offset parsing, fuzz inputs targeting the skip-field logic.
Related errors
- Invalid ${label} Huffman table: oversubscribed codes
- Invalid ${label} Huffman table: incomplete codes
- Invalid ${label} Huffman table: prefix collision
- Invalid ${label} Huffman table: duplicate code
- Invalid ${this.#label} Huffman code
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8258d3c14ef853ea.
Report an issue: GitHub.