compcol::rar3::Decoder (0.6.10) decodes the single member of libarchive's regression
fixture test_read_format_rar3_lowdist_reset.rar (BSD-2-Clause, in libarchive's
libarchive/test/) incorrectly. The member lowdist-reset.bin is 64 bytes, packed 490 bytes,
method 0x35, version 29, not solid. libarchive's test expects:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 02 03 04 05 06 07 0d 0e
0f 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36
compcol 0.6.10 produces (first 40 bytes right, then diverges):
... 20 21 22 23 24 25 26 27 02 03 04 05 06 07 08 09
0a 02 82 92 a2 b2 c2 d2 f0 f7 0c 4c 8c cd 0d 4d
The file CRC (0x6ff838dc) does not match the output (0x05d56889). libarchive's fix for this
case was about resetting the low-distance table state between blocks ("lowdist reset"); the
archive's packed data is two blocks with keep tables-style headers, judging by the repeated
table prefix in the packed bytes. Reproducer: feed the 490 packed bytes to
Decoder::with_unpack_size(64) then finish.
In airlock the member fails its CRC check and the archive is held, so this is not a safety
issue there; it is a correctness gap for that archive.
A second observation, not a bug: rar5::Decoder decodes a whole block inside one decode
call before yielding output (decode_in_block runs to block end or the unpack cap), so a
caller cannot bound memory per call except through with_unpack_size; a pause when the
ready queue passes a threshold would let callers stream arbitrarily large members with
bounded memory. Likewise rar3::Decoder is buffer-then-drain by design.
compcol::rar3::Decoder(0.6.10) decodes the single member of libarchive's regressionfixture
test_read_format_rar3_lowdist_reset.rar(BSD-2-Clause, in libarchive'slibarchive/test/) incorrectly. The memberlowdist-reset.binis 64 bytes, packed 490 bytes,method 0x35, version 29, not solid. libarchive's test expects:
compcol 0.6.10 produces (first 40 bytes right, then diverges):
The file CRC (0x6ff838dc) does not match the output (0x05d56889). libarchive's fix for this
case was about resetting the low-distance table state between blocks ("lowdist reset"); the
archive's packed data is two blocks with
keep tables-style headers, judging by the repeatedtable prefix in the packed bytes. Reproducer: feed the 490 packed bytes to
Decoder::with_unpack_size(64)thenfinish.In airlock the member fails its CRC check and the archive is held, so this is not a safety
issue there; it is a correctness gap for that archive.
A second observation, not a bug:
rar5::Decoderdecodes a whole block inside onedecodecall before yielding output (
decode_in_blockruns to block end or the unpack cap), so acaller cannot bound memory per call except through
with_unpack_size; a pause when theready queue passes a threshold would let callers stream arbitrarily large members with
bounded memory. Likewise
rar3::Decoderis buffer-then-drain by design.