Search code examples
c#bouncycastlezlibdotnetzip

ZLIB.net (.NET) zeros after inflating a byte array (randomly working)


I am confused by the behavior of Deflate algorithm, such as, the first chunk of bytes (size 12~13k) always decompress successfully. But the second decompression never turns out successful..

I am using DotNetZip (DeflateStream) with a simple code, later I switched to ZLIB.Net (component ace), Org.Bouncycastle, and variety of c# libraries.

The compression goes in c++ (the server that sends the packets) with deflateInit2, windowSize (-15) -> (15 - nowrap).

What could be incorrectly going so that I'm having zeros at the end of the buffer despite the fact that the decompression went successfully?

a example code with "Org.BouncyCastle.Utilities.Zlib"
it's pretty much the same code for almost any lib (DotNetZip, ZLIB.Net, ...)

internal static bool Inflate(byte[] compressed, out byte[] decompressed) 
{
    using (var inputStream = new MemoryStream(compressed))
    using (var zInputStream = new ZInputStream(inputStream, true))
    using (var outputStream = new MemoryStream()) 
    {
        zInputStream.CopyTo(outputStream);
        decompressed = outputStream.ToArray();
    }

    return true;
}

Solution

  • To make sure everything working correctly, you should check for the following:

    • Both zlib versions match on both sides (compression - server, and decompression - client).
    • Flush mode is set to sync, that means the buffer must be synchronized in order to decompress further packets sent by the server.
    • Ensure that the packets you received is actually correct, and at my specific case, I was appending a different array size (a constant one in fact, of 0xFFFF) which might be different than the size of the received data (and that happens in most cases).

    [EDIT 13th Nov. 19']
    Keep in mind that conventionally the server may not send the last 4 bytes (sync 00 00 ff ff) if both has a contract that the flush type is sync, so be aware of adding them manually.