qoi_decode accepts truncated/no-chunk QOI streams and can allocate large output buffers from tiny files
Summary
I found that qoi_decode() / qoi_read() can accept malformed QOI streams that do not contain enough image data to produce the declared number of pixels.
In these cases, the decoder returns success instead of rejecting the input as invalid. This can also allow very small .qoi files to trigger allocation of a much larger output buffer based only on the declared dimensions.
I am reporting this as a decoder correctness and resource-amplification hardening issue, not as memory corruption. I did not observe an ASan/libFuzzer memory-corruption crash.
Affected version tested
I tested the current master branch:
commit: 97bacc86a9c4abf5a2d452102dc26546c4c670b9I did not find a direct phoboslab/qoi OSS-Fuzz project in my current google/oss-fuzz/projects checkout.
Observed behavior
The decoder accepts inputs that contain a valid QOI header but do not contain enough chunks to encode the declared pixels.
Examples:
no_chunks_1x1.qoi
size: 22 bytes
qoi_read(): decode=ok
truncated_rgba_2x1.qoi
size: 23 bytes
qoi_read(): decode=ok
no_chunks_20000000x1_rgba.qoi
size: 22 bytes
qoi_read(): decode=ok
observed RSS: about 80 MB in my local testThe last case is a 22-byte input that declares a large image and causes the decoder to allocate the full output buffer even though the file contains no actual pixel chunks.
Expected behavior
Malformed QOI streams that do not provide enough data for the declared image dimensions should be rejected.
The API documentation says:
Returns NULL if something went wrong.I would expect truncated/no-chunk streams to return NULL rather than being accepted as successfully decoded images.
Impact
This can lead to surprising successful decoding of invalid QOI data and allows small files to trigger much larger memory allocations based on declared dimensions.
I did not observe a memory-safety crash, so this should be treated as a correctness/resource-amplification issue rather than a code execution issue.
Reproduction package
I attached a minimal reproduction package without binaries:
qoi-maintainer-repro_public_minimal.zip
SHA-256: A250578ABDFDCEC2EDCB3A965A411E10FDD427659ACB22ED67E9573C7603D8B3The package contains:
README
PoCs
reproduction scripts
logs
fuzzing summary
suggested validation direction
SHA256SUMS.txtI can provide the full reproduction package with convenience binaries if useful.
Source: phoboslab/qoi