1

Closed

Zlib exception when compressed stream size is (multiple of buffer size) + header size +(0 to 7)

description

When using GZipStream to decompress a stream where the stream length is a multiple of the buffer size + header size +(0 to 7), an exception is generated thus:
 
Protocol error. AvailableBytesIn=7, expected 8
 
AvailableBytesIn varying between 0 and 7. This happens because the read routine stops reading the base stream when all the compressed data is complete: if the trailing 8 bytes (CRC, size) didn't fit into the buffer the finish() routine in ZlibStream.cs throws the above exception. I have written a fix in zlibstream.cs (starts at line 885):
 
                    // Read and potentially verify the GZIP trailer: CRC32 and  size mod 2^32
                    byte[] trailer = new byte[8];
 
                    //>>>> OLD CODE >>>>
                    //if (_z.AvailableBytesIn != 8)
                    //    throw new ZlibException(String.Format("Protocol error. AvailableBytesIn={0}, expected 8",
                    //         _z.AvailableBytesIn));
                    //
                    //Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length);
                    //>>>
                    //<<<< NEW CODE <<<<
 
                    if (_z.AvailableBytesIn != 8)
                    {
                        //  Make sure we have read to the end of the stream
                        Array.Copy(_z.InputBuffer, _z.NextIn,trailer, 0, _z.AvailableBytesIn);
                        int bytesNeeded = 8 - _z.AvailableBytesIn;
                        int bytesRead = _stream.Read(trailer,
                                                     _z.AvailableBytesIn,
                                                     bytesNeeded);
                        if (bytesNeeded != bytesRead)
                        {
                            throw new ZlibException(String.Format("Protocol error. AvailableBytesIn={0}, expected 8",
                                 _z.AvailableBytesIn + bytesRead));
                        }
                    }
                    else
                    {
                        Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length);
                    }
 
                    // <<<< END NEW CODE
 
To make it easier to verify, I'm attaching a gzipped file that causes problems when the buffer size is the default 8192 bytes.

file attachments

Closed Sep 5, 2009 at 4:22 PM by Cheeso
fixed in changeset #42377

comments

Cheeso wrote Sep 5, 2009 at 3:53 PM

I Love bug reports that come with proposed fix code. Thanks!