Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

write::BzDecoder: Fix infinite loop on drop when no data is read or written #118

Merged

Conversation

chenxiaolong
Copy link
Contributor

If writes to the BzDecoder end before it has been fed the entire stream and the output buffer has already been flushed to the wrapped writer, then the Drop implementation will loop forever. On drop, try_finish() is called, which repeatedly tries to write() until BZ_STREAM_END is returned or an error occurs, but neither scenario happens if there's no input nor output data to process.

This commit makes try_finish() return an UnexpectedEof error in this scenario.


(Also, really happy to see this library found a new maintainer!)

chenxiaolong and others added 3 commits December 11, 2024 19:26
…ritten

If writes to the BzDecoder end before it has been fed the entire stream
and the output buffer has already been flushed to the wrapped writer,
then the Drop implementation will loop forever. On drop, try_finish() is
called, which repeatedly tries to write() until BZ_STREAM_END is
returned or an error occurs, but neither scenario happens if there's no
input nor output data to process.

This commit makes try_finish() return an UnexpectedEof error in this
scenario.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
let _ = self.write(&[])?;
// The write is effectively a `self.flush()`, but we want to know how many
// bytes were written. exit if no input was read and no output was written
if self.write(&[])? == 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I removed the self.total_in() == read_before check here because on self.write(&[])? there is no way (unless I'm really missing something) that total_in could change: that empty input buffer is handed to decompress_vec, which ultimately calls BZ2_bzDecompress with an empty input buffer. total_in will not change in that case, how could it?

src/write.rs Outdated Show resolved Hide resolved
Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com>
@folkertdev folkertdev merged commit 427c709 into trifectatechfoundation:master Dec 16, 2024
11 checks passed
@chenxiaolong
Copy link
Contributor Author

Thanks for improving the PR and merging it!

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.

3 participants