Skip to content

Make the decode window size limit configurable - #111

Merged
KillingSpark merged 3 commits into
KillingSpark:masterfrom
LucaCappelletti94:configurable-max-window-size
Jul 1, 2026
Merged

Make the decode window size limit configurable#111
KillingSpark merged 3 commits into
KillingSpark:masterfrom
LucaCappelletti94:configurable-max-window-size

Conversation

@LucaCappelletti94

Copy link
Copy Markdown
Contributor

ruzstd caps the decode window at a hardcoded 100 MB with no override, so it cannot decode frames declaring a larger window such as anything from zstd --long. This adds an opt-in to raise the cap while keeping the 100 MB default for everyone else, mirroring ZSTD_d_windowLogMax in libzstd. My use case is streaming a 2 GiB-window corpus from pure Rust without pulling in C libzstd.

It also makes the cap apply to the first frame of a stream, which new skipped while reset enforced it, and reshapes FrameDecoderError::WindowSizeTooBig to report the effective limit. That last piece is a small breaking change on the unreleased 0.8.4 that I can drop if you prefer strictly non-breaking.

@zleyyij zleyyij left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than semantic discussion around the signature of FrameDecoderState::new(), this PR seems structurally sound and a reasonable enough addition.

I'm just contributing a review, and don't have final say.

Good work!

Comment thread ruzstd/src/decoding/frame_decoder.rs Outdated

impl FrameDecoderState {
pub fn new(source: impl Read) -> Result<FrameDecoderState, FrameDecoderError> {
pub fn new(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid a breaking change, we could keep the old function signature and use DEFAULT_MAX_WINDOW_SIZE in new(), and expect people to call set_max_window_size() if they want to update it.

This would keep the new() interface streamlined and sufficient for most usecases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The public FrameDecoder::new() already works that way. The signature in the diff is the private FrameDecoderState, now a plain fn to make that obvious.

@KillingSpark

KillingSpark commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Thanks for the work!

@zleyyij maybe I am missing something but I think the signature with a breaking change is on the non-public FrameDecoderState and not the public FrameDecoder itself. If that's the case this PR looks good to me but since you brought it up I want to make sure I did not miss a breaking change there :)

The change in the error type is fine for me, I have no issue bumping to a 0.9 version instead of the next 0.8

@LucaCappelletti94

Copy link
Copy Markdown
Contributor Author

Thanks for the work!

@zleyyij maybe I am missing something but I think the signature with a breaking change is on the non-public FrameDecoderState and not the public FrameDecoder itself. If that's the case this PR looks good to me but since you brought it up I want to make sure I did not miss a breaking change there :)

The change in the error type is fine for me, I have no issue bumping to a 0.9 version instead of the next 0.8

The parameter is only on the private FrameDecoderState, the public FrameDecoder::new() is unchanged. I also dropped its leftover confusing pub so it clearly reads as internal. The only public break is the WindowSizeTooBig reshape.

@LucaCappelletti94

Copy link
Copy Markdown
Contributor Author

will fix

@KillingSpark
KillingSpark merged commit 1f0f513 into KillingSpark:master Jul 1, 2026
2 checks passed
@KillingSpark

Copy link
Copy Markdown
Owner

Thanks again :)

) -> Result<FrameDecoderState, FrameDecoderError> {
let (frame, header_size) = frame::read_frame_header(source)?;
let window_size = frame.window_size()?;
Self::check_window_size(window_size, max_window_size)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding this check. I think before malicious input could have triggered OOM.

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.

4 participants