zlib膨胀返回一个缓冲区错误。

时间:2022-10-10 20:01:32

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?

我正在尝试使用zlib解压缩一个zip文件(不使用任何扩展或第三方)。最初,src_len是48756255,而dest_len是49209890。while循环的第一个传递是fine: err是Z_OK,第二个是通过start。在第二个通道上,无论我做什么,我都会从膨胀中得到Z_BUF_ERROR。流。此时的total_out是49034460,所以剩下的部分是流。第二次通过的时候是0。在任何情况下,我都期望膨胀给我Z_STREAM_END。我真的不知道发生了什么,有人能帮忙吗?

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 个解决方案

#1


5  

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.

通过使用可用的输出来处理尽可能多的输入。一旦它既不能处理输入,也不能产生输出,它将返回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.

在这种情况下,所有的输入都是经过处理的,并且有多余的输出空间,但是没有检测到流的末端。您没有得到Z_STREAM_END,因为某些原因您没有提供一个完整的压缩流。

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.

以下是对您的代码的一些其他评论。您的循环不做任何事情,并且在循环中设置next_out和avail_out,因为您什么都不做。您在循环中没有提供新的输入或新的输出空间,因此没有必要进行循环。围绕膨胀()的唯一目的是提供更多的输入,提供更多的输出空间,或者两者都有。此外,当虚增()返回时,next_out和avail_out被更新到输出缓冲区中的下一个可用位置和那里可用空间的数量。在循环中设置next_out和avail_out的语句将它们设置为它们已经拥有的值。

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.

在使用适当的循环来进行膨胀()的代码中,Z_BUF_ERROR不是问题,并且处理可以继续。但是,如果您期望在下一次调用膨胀()时得到不同的结果,则必须提供更多的输入和/或更多的输出空间。

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

不需要使用零结构来初始化流。接下来的作业是您所需要的。

#1


5  

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.

通过使用可用的输出来处理尽可能多的输入。一旦它既不能处理输入,也不能产生输出,它将返回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.

在这种情况下,所有的输入都是经过处理的,并且有多余的输出空间,但是没有检测到流的末端。您没有得到Z_STREAM_END,因为某些原因您没有提供一个完整的压缩流。

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.

以下是对您的代码的一些其他评论。您的循环不做任何事情,并且在循环中设置next_out和avail_out,因为您什么都不做。您在循环中没有提供新的输入或新的输出空间,因此没有必要进行循环。围绕膨胀()的唯一目的是提供更多的输入,提供更多的输出空间,或者两者都有。此外,当虚增()返回时,next_out和avail_out被更新到输出缓冲区中的下一个可用位置和那里可用空间的数量。在循环中设置next_out和avail_out的语句将它们设置为它们已经拥有的值。

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.

在使用适当的循环来进行膨胀()的代码中,Z_BUF_ERROR不是问题,并且处理可以继续。但是,如果您期望在下一次调用膨胀()时得到不同的结果,则必须提供更多的输入和/或更多的输出空间。

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

不需要使用零结构来初始化流。接下来的作业是您所需要的。