* Fix two bugs causing premature exiting the PPMd decompression
1. PPMd doesn't use a buffer to read input data, it reads data
byte-by-byte, and it doesn't have a loop to process the whole
requested size buffer-by-buffer, but still has a cap of maximum
input bytes set to `INT16_MAX`. As a result, the decompression
function never decodes more bytes than this number and exits.
2. The byte-by-byte decoding loop decrements `avail_in` together
with `avail_out`, but 1 byte of compressed data doesn't mean
1 byte of compressed data. This results in that the
decompression ends after writing `avail_in` of *decompressed*
data, which is always less than the requested size.
Fix the first one by removing the cap of `INT16_MAX` and using the
real boundaries (`max_avail_in`) if set or just `INT64_MAX` (the
decoding loop checks the available output size as well, thus it
couldn't go OOB).
Fix the second one by tracking how many *compressed* bytes were
actually read and exit only when the actual limit is exhausted.
This removes the need of calling mz_zip{,_reader}_entry_read()
in a loop when the ZIP is compressed with PPMd and the caller
wants to read the whole file or a chunk larger than the
compressed size (or `INT16_MAX`).
Tested on Windows w/clang-cl and a PPMd-compressed ZIP containing
up to 700 Kb -sized files.
Signed-off-by: Alexander Lobakin <alobakin@mailbox.org>
* Fix a potential OOB read in the PPMd reader callback
We check that total_in < max_total_in in the decoding loop, but
turns out that one PPMd decoding iteration may consume more than
1 byte of input.
To make sure it won't go past the limit, add an additional check
to the reader callback itself just to be safe.
The actual check in the decoding loop is left as-is as there, it's
a valid case and should not result in an error, but in the reader
callback, it's closer to the "Insufficient input data" case handled
below, so return `MZ_STREAM_ERROR`.
Suggested-by: CodeRabbit AI
Signed-off-by: Alexander Lobakin <alobakin@mailbox.org>
---------
Signed-off-by: Alexander Lobakin <alobakin@mailbox.org>