ZLIB inflate give 'data error' in PHP

2019-08-10 01:36发布

I've got a file that has zlib deflated blocks of 4096 bytes. I'm able to inflate at least 1 block of 4096 bytes with C++, using Minzip's inflate implementation, without garbled text or data error.

I'm using the following C++ implementation to inflate the data:

#define DEC_BUFFER_LEN 20000
int main(int argc, char* argv[]) {
    FILE *file = fopen("unpackme.3di", "rb");

    char *buffer = new char[4096];

    std::fstream outputFile;
    outputFile.open("output.txt", std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);


    // Data zit nu in de buffer
    char *decbuffer = new char[DEC_BUFFER_LEN];

    mz_streamp streampie = new mz_stream();

    streampie->zalloc = Z_NULL;
    streampie->zfree = Z_NULL;
    streampie->opaque = Z_NULL;
    streampie->avail_in = Z_NULL;
    streampie->next_in = Z_NULL;

    if (inflateInit(streampie) != Z_OK)
        return -1;

    fread(buffer, 1, 4096, file);

    streampie->next_in = (Byte *)&buffer[0];
    streampie->avail_in = 4096;

    streampie->next_out = (Byte *)&decbuffer[0];
    streampie->avail_out = DEC_BUFFER_LEN;

    streampie->total_out = 0;

    int res = inflate(streampie, Z_NO_FLUSH);

    if (res != Z_OK && res != Z_STREAM_END) {
        std::cout << "Error: " << streampie->msg << std::endl;
        return;
    }
    outputFile.write(decbuffer, streampie->total_out); // Write data to file

    fclose(file);

    inflateEnd(streampie);

    outputFile.flush();
    outputFile.close();

    getchar();

    return 0;
}

and I'm using the following PHP implementation:

function Unpack3DI($inputFilename) {
    $handle = fopen($inputFilename, 'rb');
    if ($handle === false) return null;

    $data = gzinflate(fread($handle, 4096));
    return $data;
}


var_dump(Unpack3DI('unpackme.3di'));

Result:

Warning: gzinflate() [function.gzinflate]: data error in /var/www/html/3di.php on line 9
bool(false)

标签: php zlib inflate
1条回答
爷的心禁止访问
2楼-- · 2019-08-10 02:26

The issue was that I used the wrong function. I had to use gzuncompress instead of gzinflate. Also, pushing the whole file in gzuncompress did the job very well actually, as zlib checks if there are remaining blocks to be uncompressed.

More information about the Zlib methods in PHP are answered in this answer to "Which compression method to use in PHP?".

查看更多
登录 后发表回答