zlib:解压缩大文件会导致“无效的代码长度设置”错误

问题描述 投票:0回答:1

我尝试使用 zlib 来检测压缩 gz 数据流的结尾。 我不需要未压缩的内容,我的目标是获取指向流的开头和结尾的指针。 我的代码适用于小文件,但适用于大文件。尝试为 outbuf 分配更多内存,但没有成功。 主要是从zlib的例子复制粘贴过来的,有什么问题吗?

// fopen(filename,"rb")...fread(inbuf, inlen, 1, fd);

int gzip_dctest(unsigned char *inbuf, unsigned int inlen) {

    unsigned int outlen = 262144;
    unsigned char *outbuf = malloc(outlen);
    int ret = 0;

    z_stream infstream;

    /* allocate inflate state */
    infstream.zalloc = Z_NULL;
    infstream.zfree = Z_NULL;
    infstream.opaque = Z_NULL;
    infstream.avail_in = 0;
    infstream.next_in = Z_NULL;

    ret = inflateInit2(&infstream, MAX_WBITS | 32); // gzip/zlib header autodetect
    if (ret != Z_OK) {
        fprintf(stderr, "gzip_test: init fail (%d: %s)\n", ret, infstream.msg);
        return ret;
    }
    
    unsigned int ptr = 0;
    /* decompress until deflate stream ends or end of file */
    do {
        infstream.next_in = inbuf + ptr;
        infstream.avail_in = inlen - ptr;

        if (infstream.avail_in > (outlen / 8)) infstream.avail_in = (outlen / 8); // get chunk size
        if (infstream.avail_in == 0)
            break;

        /* run inflate() on input until output buffer not full */
        do {
            ptr += infstream.avail_in;

            infstream.avail_out = outlen;
            infstream.next_out = outbuf;

            ret = inflate(&infstream, Z_NO_FLUSH);
            if (ret < 0) {
                    fprintf(stderr, "gzip_test: inflate fail at %u (%d: %s)\n", ptr - infstream.avail_in, ret, infstream.msg);
                    return ret;
            }

        } while (infstream.avail_out == 0);
    
        /* done when inflate() says it's done */
    } while (ret != Z_STREAM_END);

    inflateEnd(&infstream);
    return ptr - infstream.avail_in;
}

问题文件的示例输出(403709952 未压缩,99152355 压缩大小):

gzip_test: inflate fail at 2374700 (-3: invalid code lengths set)

此文件上的“gzip -d”没有给出错误。 “1.cpio.gz:75.4%——替换为1.cpio” 如果我再次压缩它(gzip 命令),我的代码中会出现另一个错误:

gzip_test: inflate fail at 2381863 (-3: invalid block type)

期望任何文件大小的工作代码。

c gzip zlib inflate
1个回答
0
投票

您的

ptr += infstream.avail_in;
需要移到内部
do
循环之外。然后就可以正常使用了。

您还需要在返回之前添加

free(outbuf);
,无论是错误还是成功。

© www.soinside.com 2019 - 2024. All rights reserved.