What is checked, and when¶
Block CRCs, before the block's bytes¶
Every block's CRC is checked before any of that block's bytes are returned. A block whose CRC does not match returns none of its bytes: the error comes instead. The bytes returned before an error are exactly the stream's up to the bad block.
Stream CRCs, at the stream's end¶
Each stream's combined CRC is checked at the stream's end. The bytes of a stream's blocks are returned as each block is verified, before the stream's own CRC has been read. So a streaming caller has the whole stream verified only once a read reaches its end without an error: until then, what it has read is provisional.
In Python, BZ2Reader.verified turns true only when a read
returns the end with every block's and stream's CRC matched.
Where an error was found¶
An error says where decoding failed: in Rust Error { kind, block, bit }, in Python the
DecodeError message. That is which block, and the bit it starts at. A damaged bit can be
found later than where it lies, since the input is only known to be wrong once something
it encodes fails a check.
The error kinds (ErrorKind):
- the input:
Empty,NotBz2,Truncated,TrailingData; - each of libbzip2's block checks:
BadBlockMagic,BadOrigPtr,NoSymbols,BadGroups,BadSelectors,BadSelector,BadCodeLength,BadHuffmanCode,SelectorOverrun,RunTooLong,BlockTooLong,RunUnfinished; BlockCrcandStreamCrc, with the stored and computed values;- this decoder's refusals:
Randomised,BlockTooLarge; Io(from aBzReader's source),RangeOvershoot,Cancelled, andInternal(a caught panic: a bug).
What is decoded, and what is refused¶
The format is libbzip2 1.0.8's, with every check it makes: bzip2 1.0 and later output. Four choices differ from it, and each has its own error:
| input | libbzip2 | mibz2 |
|---|---|---|
| randomised blocks (written only by bzip2 0.9.0 and earlier, before 1999) | decoded | refused (Randomised) |
| bytes after the last stream that do not begin another stream | ignored | an error (TrailingData): nothing after a stream is silently dropped |
| an oversubscribed Huffman code pointing past the alphabet | a stale table entry read | an error |
| a block whose compressed form passes 64 MiB (a real block is at most about 4.2 MB) | decoded | an error (BlockTooLarge) |