[Mono-bugs] [Bug 593480] New: DeflateStream doesn't handle end of input Stream properly

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Fri Apr 2 15:52:54 EDT 2010


http://bugzilla.novell.com/show_bug.cgi?id=593480

http://bugzilla.novell.com/show_bug.cgi?id=593480#c0


           Summary: DeflateStream doesn't handle end of input Stream
                    properly
    Classification: Mono
           Product: Mono: Class Libraries
           Version: 2.6.x
          Platform: i686
        OS/Version: Mac OS X 10.5
            Status: NEW
          Severity: Normal
          Priority: P5 - None
         Component: System
        AssignedTo: mono-bugs at lists.ximian.com
        ReportedBy: cfbradford at gmail.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---
           Blocker: ---


User-Agent:       Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US;
rv:1.9.2) Gecko/20100115 Firefox/3.6

I'm trying to inflate chunks of data stored in a .zip archive.

When I link the DeflateStream directly to the zip's FileStream, things seems to
work fine:

using (DeflateStream deflate = new DeflateStream(stream,
CompressionMode.Decompress, true))
{
    try
    {
        actualCrc32 = Crc32(deflate, header.ActualSize);
    }
    catch (IOException e)
    {
        Log("*** Deflate error: {0} ***", e);
    }
}

However, the DeflateStream reads more data than needed to fill its 4k buffer
which then requires a seek on the underlying stream before the next file in the
archive can be read. To try and avoid this seek and the resulting buffer flush
and re-read, I tried to read just the compressed data into a MemoryStream and
pass that to the DeflateStream:

const int PADDING = 0;
byte[] buffer = new byte[header.CompressedSize + PADDING];
stream.Read(buffer, 0, (int)header.CompressedSize);

using (MemoryStream ms = new MemoryStream(buffer))
using (DeflateStream deflate = new DeflateStream(ms,
CompressionMode.Decompress, true))
{
    // ... same as before ...
}

This works for some of the files in the archive, but others hit the
DeflateStream's EOF before they should. Typically only one byte is missing, but
I've seen as many as 200+ bytes missing from the output.

If I increase the value of PADDING in the sample above (so that extra
zero-bytes are available to the DeflateStream) then everything works as
expected.

Since I'm performing a CRC check on the inflated results, I'm fairly certain
that the *values* of those extra padding bytes don't matter (any extra bytes
that are read in the first example are non-zero values for the next file header
whereas they are all zeros in the MemoryStream case).

It seems as if the DeflateStream isn't flushing its underlying buffers properly
when its input stream runs out of data. If the compressed file happens to be
the correct size to be used completely in one of the iterations of the inner
loop, then everything is fine. If the internal processing buffer is only
partially filled when the input stream runs out of data, it doesn't seem like
that remaining data is being processed. Providing extra dummy data to help fill
that buffer and allow the remaining real data to be processed seems to work,
but shouldn't be necessary.

Reproducible: Always

Steps to Reproduce:
1.
2.
3.

-- 
Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list