Skip to content

Bound DEFLATE block output buffering in decoder - #4

Merged
sile merged 2 commits into
mainfrom
fix/bound-deflate-block-output-buffering
Sep 6, 2026
Merged

sile merged 2 commits into
mainfrom
fix/bound-deflate-block-output-buffering

Conversation

@sile

@sile sile commented Sep 6, 2026 •

Copy link
Copy Markdown
Owner

Bound the streaming DEFLATE decoder's internal output buffer.

A single DEFLATE block can expand arbitrarily (RFC 1951 has no per-block
maximum), so one highly-compressible block was fully expanded into the internal
buffer before control returned to the caller. The decoder now caps the unread
output at ~64 KiB and yields back, resuming from the saved position.

Ref: sile/libflate#92, sile/libflate#90

sile added 2 commits September 6, 2026 21:17
A single DEFLATE block can expand arbitrarily (RFC 1951 has no per-block
maximum), so one highly-compressible block could be fully expanded into the
decoder's internal output buffer before the caller had a chance to drain it,
allowing memory to grow without bound (libflate issue #90 / PR #92 analogue).

- Add MAX_INTERNAL_BUFFER (64 KiB) cap to step_symbol_loop: once unread output
  reaches the cap the decoder yields (StepOutcome::Yield), preserving the
  SymbolLoop state (is_final, Huffman decoders, bit position) so decoding
  resumes on the next feed(). drive() treats Yield as a break and feed returns
  control so the caller can drain output()/advance().
- Update the deflate/gzip/zlib drain loops to resume after a cap yield and to
  collect the final block's output before checking is_finished(); previously a
  resume that finished mid-block truncated the trailing partial block.
- Add regression tests: single 8 MiB block does not buffer whole output, and
  partial-final-block roundtrips for gzip/zlib.

All 73 unit tests, integration tests, and doctests pass; clippy and rustfmt
are clean. The public streaming API is unchanged.
@sile
sile merged commit 5d66eb3 into main Sep 6, 2026
9 checks passed
@sile
sile deleted the fix/bound-deflate-block-output-buffering branch September 6, 2026 12:40
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.

1 participant