can1357/oh-my-pi · error · ArchiveError
Invalid ARJ method-4 compressed data: match exceeds declared
Error message
Invalid ARJ method-4 compressed data: match exceeds declared size
What it means
Method 4 is an LZ77-style scheme: a length code decodes to a match of `lengthCode + 2` bytes copied from earlier output. The decoder validates that the match fits within the declared output size (outSize); a match that would overrun it means the stream's declared size and its contents disagree, so it throws instead of writing past the output buffer.
Source
Thrown at packages/utils/src/ar/arj.ts:139
function decompressArjMethod4(packed: Uint8Array, outSize: number): Uint8Array {
const reader = new ArjBitReader(packed);
const output = new Uint8Array(outSize);
let outputPosition = 0;
while (outputPosition < outSize) {
let lengthCode = 0;
let lengthWidth = 0;
for (; lengthWidth < 7; lengthWidth++) {
if (reader.read(1) === 0) break;
lengthCode += 2 ** lengthWidth;
}
if (lengthWidth !== 0) lengthCode += reader.read(lengthWidth);
if (lengthCode === 0) {
output[outputPosition++] = reader.read(8);
continue;
}
const length = lengthCode + 2;
if (length > outSize - outputPosition) {
throw new ArchiveError("Invalid ARJ method-4 compressed data: match exceeds declared size");
}
let positionCode = 0;
let positionWidth = 9;
for (; positionWidth < 13; positionWidth++) {
if (reader.read(1) === 0) break;
positionCode += 2 ** positionWidth;
}
positionCode += reader.read(positionWidth);
if (positionCode >= 26_624 || positionCode >= outputPosition) {
throw new ArchiveError("Invalid ARJ method-4 compressed data: history distance is out of range");
}
let sourcePosition = outputPosition - positionCode - 1;
for (let index = 0; index < length; index++) output[outputPosition++] = output[sourcePosition++]!;
}
reader.assertZeroPadding();
return output;
}
View on GitHub (pinned to 9690622007)
Solutions
- Check that outSize equals the member's original (uncompressed) size from the ARJ header — this is the most common cause when calling decompressArjMethod4 directly.
- Confirm the packed bytes belong to that member (correct offset and compressedSize from the index).
- Test the archive externally to confirm the member is intact; if corrupt, restore from a known-good copy.
- If you truncated output intentionally (partial extraction), decompress with the full declared size and slice afterwards — never shrink outSize.
Example fix
// before: passing compressed size as the output size const out = decompressArjMethod4(packed, entry.compressedSize); // after: use the declared original size const out = decompressArjMethod4(packed, entry.originalSize);
Defensive patterns
Strategy: validation
Validate before calling
// outSize must be the member's original (uncompressed) size, not its compressed size
if (typeof entry.originalSize !== "number" || entry.originalSize < 0) {
throw new Error(`Member ${entry.name}: missing original size for method-4 decompression`);
}
const out = decompressArjMethod4(packed, entry.originalSize); Try / catch
try {
return decompressArjMethod4(packed, originalSize);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("match exceeds declared size")) {
throw new Error(`Member ${name}: declared size ${originalSize} disagrees with compressed stream`);
}
throw err;
} Prevention
- Always pass the header-declared original size as outSize; never reuse compressedSize or stale index values.
- For partial extraction, decompress fully then slice — do not shrink outSize.
- Validate index entries against headers before decompression.
When it happens
Trigger: decompressArjMethod4(): the decoded length (lengthCode+2) exceeds outSize - outputPosition at the current output offset. Caused by a corrupted length code, an outSize that is smaller than the original uncompressed size, or a stream concatenated from the wrong member.
Common situations: Passing an incorrect outSize (e.g. using the compressed size or a stale index entry) when calling the decompressor directly, corrupt length bits from data damage, or a fuzzed archive crafted to overrun buffers.
Related errors
- Invalid ARJ method-4 compressed data: truncated bitstream
- Invalid ARJ method-4 compressed data: non-zero trailing bits
- Invalid ARJ method-4 compressed data: history distance is ou
- Invalid ARJ archive: truncated ${what}
- Invalid ARJ ${field}: missing terminator
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8043d159e1ea206e.
Report an issue: GitHub.