trifectatechfoundation / zlib-rs

A safer zlib
zlib License
147 stars 15 forks source link

Fails to decompress gzip streams at some chunk sizes #172

Closed glandium closed 2 months ago

glandium commented 2 months ago

The following testcase, derived from https://github.com/web-platform-tests/wpt/blob/master/compression/decompression-split-chunk.tentative.any.js , fails with libz-rs-sys:

#include <zlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char*argv[]) {
    int exitcode = 0;
    Bytef buf[] = { 31, 139, 8, 0, 0, 0, 0, 0, 0, 3, 75, 173, 40, 72, 77, 46, 73, 77, 81, 200, 47, 45, 41, 40, 45, 1, 0, 176, 1, 57, 179, 15, 0, 0, 0 };
    for (uInt chunk = 1; chunk <= sizeof(buf); chunk++) {
        Bytef out[1024];
        z_stream zs;
        memset(&zs, 0, sizeof(zs));
        int ret = inflateInit2(&zs, 31);
        assert(ret == Z_OK);
        zs.avail_out = sizeof(out);
        zs.next_in = buf;
        zs.next_out = out;
        while (ret == Z_OK && zs.total_in < sizeof(buf)) {
            zs.avail_in = chunk > sizeof(buf) - zs.total_in ? sizeof(buf) - zs.total_in : chunk;
            ret = inflate(&zs, Z_NO_FLUSH);
        }
        if (ret != Z_STREAM_END) {
            fprintf(stderr, "Finished with %d at chunk size %u\n", ret, chunk);
            exitcode = 1;
        }
        if (memcmp(out, "expected output", zs.total_out) != 0) {
            fprintf(stderr, "Output did not match at chunk size %u\n", chunk);
            exitcode = 1;
        }
    }
    return exitcode;
}

It prints:

Finished with -3 at chunk size 8
Finished with -3 at chunk size 11
Finished with -3 at chunk size 16
Finished with -3 at chunk size 17
Finished with -3 at chunk size 31
Finished with -3 at chunk size 32
Finished with -3 at chunk size 33
Finished with -3 at chunk size 34

Note; the output check is just an extra check, it doesn't exhibit anything going wrong.