"Bad CRC32 in GZIP trailer" error if I don't read the whole stream

Apr 25, 2013 at 11:44 PM
Edited Apr 25, 2013 at 11:44 PM
I'm using the GZipStream as a drop in replacement for the .Net one. For one operation I open with a binary reader and just read a string from the start of the file.

When i close the BinaryReader I get Bad CRC32 in GZIP trailer

Same question shows up from 2011 on Stack Overflow
http://stackoverflow.com/questions/7462220/am-i-really-forced-to-readtoend-a-streamreader-reading-an-ionic-zlib-gzipstrea

I'm running 1.9.1.8 - it worked with the .Net version but the .Net version doesn't run on the xbox and doesnt compress well.

This is the code:
using (var fs = File.Open(Filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
   using (var compress = new GZipStream(fs, CompressionMode.Decompress))
   {
     var reader = new BinaryReader(compress);
     Name = reader.ReadString();
     reader.Close();                            <--Exception happens here
     compress.Close();
  }
}
May 26, 2013 at 4:14 AM
I read you post having the same problem. After about an hour I realized the drive I was writing to was out of space. I cleared off a bunch of space and now I don't get the error. Not sure this is your situation but I'm guessing this was one of those errors where the real problem is not evident in the error message.
May 26, 2013 at 3:36 PM
Thanks.... I wish it was that easy but I'm trying to read not write and there's plenty of disc space.. Hopefully it will help others though.
Jun 4, 2013 at 11:13 PM
Edited Jun 6, 2013 at 6:44 PM
I found some time to dig into this.

Looking at the .Net version there is some CRC32 checking (see GZipDecoder.ReadFooter and Inflator.Decode if you have Reflector or equivalent). However that code only appears to be called as the stream is read and it gets to the end. Since GZipStream doesn't override Close or Dispose no checks are done if you close before reading to the end.

The code in DotNetZip that says //read to end of file is not doing that at all. The checksum needs 8 bytes so if there's less than 8 bytes in the buffer it reads enough bytes of the next block so that it has 8 bytes.

My workaround for this is that I've pulled the DotNetZip source into my code and modified the constructor such that it takes a bool that allows me to disable the CRC check.

This is a tough one to 'fix'. Its clearly much safer to do the checksum but it would mean adding code to read the whole file apart from the last 8 bytes - I was unable to work out how to do this safely in my experiments. On a big file this could be expensive which makes it slower then the .Net version AND a different behavior in this scenario.
May 15, 2014 at 3:16 PM
Edited May 15, 2014 at 3:16 PM
Refer to related Issue.