Skip to content

Declare BitReader::refill unsafe and document safety prerequisites #397

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

brian-pane
Copy link

No description provided.

Copy link

codecov bot commented Jul 17, 2025

Codecov Report

Attention: Patch coverage is 80.00000% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
zlib-rs/src/inflate.rs 78.57% 3 Missing ⚠️
Flag Coverage Δ
fuzz-compress ?
fuzz-decompress ?
test-aarch64-apple-darwin 92.45% <80.00%> (-0.09%) ⬇️
test-x86_64-apple-darwin 90.56% <80.00%> (-0.05%) ⬇️
test-x86_64-unknown-linux-gnu 89.63% <80.00%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
zlib-rs/src/inflate/bitreader.rs 93.96% <100.00%> (ø)
zlib-rs/src/inflate.rs 93.61% <78.57%> (-1.75%) ⬇️

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@@ -1862,15 +1862,31 @@ fn inflate_fast_help_impl<const FEATURES: usize>(state: &mut State, _start: usiz
let mut bad = None;

if bit_reader.bits_in_buffer() < 10 {
bit_reader.refill();
if bit_reader.bytes_remaining() >= 8 {
Copy link
Author

Choose a reason for hiding this comment

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

I added this check to make sure the safety precondition was met. But if there's any way to know for sure that buffer.bytes_remaining() is guaranteed to be >= 8 when this function is called, I can document that with a comment in place of the if-statement here.

@@ -1909,7 +1925,8 @@ fn inflate_fast_help_impl<const FEATURES: usize>(state: &mut State, _start: usiz
// we have two fast-path loads: 10+10 + 15+5 = 40,
// but we may need to refill here in the worst case
if bit_reader.bits_in_buffer() < MAX_BITS + MAX_DIST_EXTRA_BITS {
bit_reader.refill();
// Safety: TODO
Copy link
Author

Choose a reason for hiding this comment

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

I'm still trying to determine how it's guaranteed to be safe to call bit_reader.refill() here. I imagine there's a limit on how many times this inner loop can be executed, and that's part of the proof that we won't run out of bytes in the bit_reader's slice?

continue;
// The next loop iteration will call bit_reader.refill(), so verify that there
// are enough bytes available for that.
if bit_reader.bytes_remaining() >= 8 {
Copy link
Author

Choose a reason for hiding this comment

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

This causes a small performance regression, but it doesn't show up as statistically significant on my system.

@brian-pane
Copy link
Author

This is a work in progress, to try to address issue #305. I was able to ensure that 2 of the 3 calls to the function meet the safety preconditions. For the remaining call, the one where I currently have a TODO comment, hopefully someone more familiar with the code that calls inflate_fast_help_impl can help me figure it out.

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.

2 participants