Skip to content

Have UnfilteringBuffer track number of remaining bytes in the frame#662

Merged
fintelia merged 4 commits intoimage-rs:masterfrom
fintelia:unfilter-buf-precise-bytes
Jan 5, 2026
Merged

Have UnfilteringBuffer track number of remaining bytes in the frame#662
fintelia merged 4 commits intoimage-rs:masterfrom
fintelia:unfilter-buf-precise-bytes

Conversation

@fintelia
Copy link
Copy Markdown
Contributor

@fintelia fintelia commented Dec 8, 2025

This is an attempt to fix #605 by tracking precisely how many bytes there are left in a frame so that we don't decompress more zlib data than we need.

Doesn't fully fix the buf_independent fuzz test, but gets us closer. Will investigate more when I have a chance... Fuzzing seems to pass now.

@fintelia fintelia marked this pull request as ready for review December 10, 2025 16:56
@197g
Copy link
Copy Markdown
Member

197g commented Dec 10, 2025

I like the idea of unblocking data from the zlib backreference buffer by knowing that we won't use it again in a decompression call. That said the inflater.finish logic seems to become obsolete (for treating the symptom) once image-rs/fdeflate#59 is utilized, right? It's not that different from #644 in that regard.

@fintelia
Copy link
Copy Markdown
Contributor Author

I've thought about the buf_independent test some more, and I think there's still and additional case this PR doesn't handle. The problem is when the final bytes of the zlib stream contains an error after all of the pixel data. Decoding byte-by-byte will complete the next_frame call successfully, while the all-at-once decoder will notice the error in the same operation as reading the final row of pixels.

Though honestly the best fix might be to just adjust buf_independent to call both next_frame and finish consecutively, and not distinguish which one returns the error. (We'd still need to make sure that finish surfaced any errors that were skipped, but that would be less complicated/invasive than other alternatives)

@anforowicz
Copy link
Copy Markdown
Contributor

Though honestly the best fix might be to just adjust buf_independent to call both next_frame and finish consecutively, and not distinguish which one returns the error. (We'd still need to make sure that finish surfaced any errors that were skipped, but that would be less complicated/invasive than other alternatives)

+1


FWIW there are still cases where zlib errors are ignored - e.g. IIUC Reader::next_frame_info will call:

  • Reader::finish_decoding which calls ReadDecoder::finish_decoding_image_data which passes a None buffer to StreamDecoder
  • Reader::read_until_image_data which calls ReadDecoder::read_until_image_data which passes a None buffer to StreamDecoder.

So errors may or may not be reported depending on which client APIs are used (e.g. next_frame decodes the image and detects errors VS next_frame_info which skips to the next frame and ignores zlib errors in the current frame). And in theory the buffering patterns (e.g. when exactly UnexpectedEof is reported) may influence how client APIs are used. But I still think this is fine (and shouldn't matter for buf_independent.rs) and we should merge this PR. Thanks for putting it together!

@anforowicz
Copy link
Copy Markdown
Contributor

@fintelia / @197g - are there any remaining concerns or action items for this PR? Merging this PR will unblock/simplify the changes in another PR at #664

@fintelia fintelia merged commit 6051365 into image-rs:master Jan 5, 2026
24 checks passed
@fintelia fintelia deleted the unfilter-buf-precise-bytes branch January 5, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CorruptFlateStream { err: InsufficientInput } (works elsewhere)

3 participants