1

I'm trying to use zlib's inflate to decompress some data I received from an http packet.

The packet is as follows:

enter image description here

The packet, itself, says that it's encoded with gzip, so I think it should work. However, when I run the data through the inflate function, I get "invalid block type". To be clear, I'm only passing in the highlighted portion of the packet to the inflate function. What am I missing?

Here is the code I'm using to decompress the data:

int Decompress(const u_char* strStreamIn, int nStreamInLen, u_char* strStreamOut)
{
  int ret = -1;
  int err = -1;

  z_stream strm  = {0};
  strm.total_in  = strm.avail_in  = nStreamInLen;
  strm.total_out = strm.avail_out = nStreamInLen * 6;
  strm.next_in   = (Bytef*) strStreamIn;
  strm.next_out  = (Bytef*) strStreamOut;
  strm.zalloc    = Z_NULL;
  strm.zfree     = Z_NULL;
  strm.opaque    = Z_NULL;

  err = inflateInit2(&strm, -MAX_WBITS);
  if (err == Z_OK) {
    err = inflate(&strm, Z_FINISH);
    if (err == Z_STREAM_END) {
      ret = strm.total_out;
    }
    else {
      inflateEnd(&strm);
      return err;
    }
  }
  else {
    inflateEnd(&strm);
    return err;
  }
  inflateEnd(&strm);
  return ret;  
}
Adi Inbar
  • 12,097
  • 13
  • 56
  • 69
Drexlin
  • 31
  • 6
  • According to [this post](http://stackoverflow.com/questions/17872152/decompress-with-gz-functions-succeeded-but-failed-with-inflate-functions-using?rq=1) and [this post](http://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib?lq=1), I should be using: `inflateInit2(&strm, 16+MAX_WBITS);` But even when I do so, I get "unknown header flags set". – Drexlin Oct 24 '13 at 21:03

1 Answers1

0

Yes, you need to use inflateInit2() with the second parameter as 31 to request gzip decompression. If you are feeding it the 1f 8b 08 00 ..., then you won't get "unknown header flags set". That must not be what you're doing.

By the way, it does nothing to set total_in and total_out where you do, since they are set to zero by inflateInit[2](). Setting them to the values you did in an effective location, e.g. after inflateInit, makes no sense either.

Setting avail_out to six times the input size is a guess, and won't always be sufficient. If it's not sufficient, then you'll get an error with Z_FINISH. You should be using a loop to call inflate() as many times as needed to process the input and produce the output.

I recommend that you read zlib.h, and then read how to use zlib.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • Mark, thanks for confirming that my code is (mostly) correct, and after taking your suggestion and looking closer at the data I'm passing in, I found the problem. There was a bug in a function that I wrote that copies one buffer to another one. I also removed the initialization of `total_in` and `total_out`. I set `avail_out` to 6 times the input just to get the function working. I'm now going to fix that to be more accurate. Thanks for all your help! – Drexlin Oct 25 '13 at 13:16