zlib inflate returning a buffer error

限于喜欢 提交于 2020-01-25 02:57:08

问题


I'm trying to decompress a zip file using zlib (without using any extension or 3rd party). Initially, the src_len is 48756255, and the dest_len is 49209890. The first pass in the while loop is fine: err is Z_OK and the second pass through starts. On the second pass, no matter what I do I get a Z_BUF_ERROR from inflate. stream.total_out at this point is 49034460, so there is a bit remaining but stream.avail_in on the second pass is 0. In any case, I would expect inflate to give me Z_STREAM_END. I really don't know what's going on, can anyone help?

void compression::uncompress2(char* dest, unsigned dest_len, char* src, unsigned src_len) {
    TempAllocator ta;

    z_stream_s stream = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    stream.next_in = (Bytef*)src;
    stream.avail_in = (uInt)src_len;
    stream.next_out = (Bytef*)dest;
    stream.avail_out = (uInt)dest_len;
    stream.zalloc = zalloc;
    stream.zfree = zfree;
    stream.opaque = &ta;

    // no header
    int err = inflateInit2(&stream, -MAX_WBITS);
    XENSURE(err == Z_OK);

    bool done = false;
    while (!done) {    
        stream.next_out = (Bytef*)(dest + stream.total_out);
        stream.avail_out = dest_len - stream.total_out;

        err = inflate(&stream, Z_SYNC_FLUSH);
        if (err == Z_STREAM_END)
            done = true;
        else if (err != Z_OK) {
            break;
        }
    }

    err = inflateEnd(&stream);
    XENSURE(err == Z_OK);
}

回答1:


inflate() will process as much input as possible using the available output. Once it can neither process input nor produce output, it will return Z_BUF_ERROR.

In this case, all of the input is processed and there is output room to spare, but the end of the stream is not detected. You are not getting Z_STREAM_END because for some reason you are not providing a complete deflate stream.

Here are some other comments on your code. Your loop does nothing, and setting next_out and avail_out in the loop as you do does nothing. You are providing no new input nor new output space in your loop, so there is no point in having a loop. The only purpose of having a loop around inflate() is to either provide more input, provide more output space, or both. Furthermore when inflate() returns, next_out and avail_out are updated to the next available location in the output buffer and the amount of available space there. Your statements that set next_out and avail_out in the loop set those to the values they already have.

In code with proper loops around inflate(), a Z_BUF_ERROR is not a problem, and the processing can continue. Though if you expect a different result on the next call of inflate(), more input and/or more output space must be provided.

There is no need to initialize stream with a structure of zeros. The subsequent assignments are all you need.



来源:https://stackoverflow.com/questions/28283334/zlib-inflate-returning-a-buffer-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!