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

Add tests for reading with an empty buffer, and fix bug in GzDecoder #150

Merged
merged 2 commits into from
Mar 16, 2018

Conversation

mdsteele
Copy link
Contributor

I recently ran into a problem where I was wrapping a flate2::read::GzDecoder inside another reader, and the outer reader ended up calling read() on the GzDecoder with an empty buffer, and instead of just returning Ok(0), the GzDecoder returned an InvalidInput error with the message: "corrupt gzip stream does not have a matching checksum".

Here's a simple test case to reproduce (without the need for the outer writer):

extern crate flate2;

// Compress some data with gzip:
let original: &[u8] = b"Lorem ipsum dolor sit amet.";
let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default());
encoder.write_all(original).unwrap();
let encoded: Vec<u8> = encoder.finish().unwrap();

// Now decompress it again:
let mut decoder = flate2::read::GzDecoder::new(encoded.as_slice());
assert_eq!(decoder.read(&mut []).unwrap(), 0);  // This call to read() fails
let mut decoded = Vec::new();
decoder.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded.as_slice(), original);

The contract for Read::read() doesn't seem to require implementations to return Ok(0) when the buffer is empty (instead of blocking or returning an error), but it seems like the nice thing to do. Even if GzDecoder wanted to return an error in this case, "corrupt gzip stream does not have a matching checksum" is definitely misleading (and in fact, it took me some time to track down the cause).

Interestingly, the other Read impls in flate2 seem to handle read(&mut []) just fine (e.g. if you replace Gz with Zlib in the above test); it's just GzDecoder that breaks.

This PR adds a simple 3-line fix for GzDecoder, along with a bunch of unit tests.

@alexcrichton alexcrichton merged commit 533cae9 into rust-lang:master Mar 16, 2018
@alexcrichton
Copy link
Member

Awesome, thanks!

@mdsteele mdsteele deleted the empty branch March 17, 2018 16:00
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