I updated the project code from the 1998 zlib version to the 2013 zlib version. One thing that seems to have changed is that the use_crc flag was used in the uncompress function, which seemed to be missing:
int ZEXPORT uncompress (dest, destLen, source, sourceLen, use_crc) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; int use_crc;
( UPDATE: as @Joe pointed out, this is probably a third-party modification . Accordingly updated. The rest of the question is still applicable, as in: “How do I best do this with today's zlib stock.”)
In the code I'm learning, uncompress () is called by deconstructing the binary .zip format and passing the "payload" of the data. The code passed the crc flag as 1. If the flag was not used, it will receive Z_DATA_ERROR (-3). (A zlib without the use_crc flag gets Z_DATA_ERROR just as if the flag were false.)
In experiments, I found that very small files worked without use_crc. Then the small counting files switched to non-working between "12345678901234" and "123456789012345" . The reason was that the first file that was photographed instead of the saved uncompressed (which zip code is called “6%” savings)
In trying to get zlib to accept it, I tried a lot of things. This included an attempt to 16 + MAX_WBITS . Nothing seemed to handle the payload from zip test.zip test.txt , as the old code did.
If I were ready to subtract one of my destination size, I seemed to be able to suppress the erroneous check ... when losing one byte. Here's a simple test program with minimal zip hardcoded payload:
#include <stdio.h> #include "zlib.h" int main(int argc, char *argv[]) { char compressed[] = { 0x78, 0x9C, 0x33, 0x34, 0x32, 0x36, 0x31, 0x35, 0x33, 0xB7, 0xB0, 0x34, 0x30, 0x04, 0xB1, 0xB8, 0x00, 0x31, 0x30, 0xB1, 0x30, 0x10, 0x00, 0x00, 0x00 }; // last 4 bytes are size (16) char uncompressed[16 + 1]; // account for null terminator int ret; z_stream strm; memset(uncompressed, 'X', 16); uncompressed[16] = '\0'; strm.zalloc = strm.zfree = strm.opaque = Z_NULL; strm.total_out = 0; strm.avail_in = 25; strm.next_in = compressed; ret = inflateInit2(&strm, MAX_WBITS /* + 16 */); // it is Z_OK strm.avail_out = 15; // 16 gives error -3: "incorrect header check" strm.next_out = uncompressed; ret = inflate(&strm, Z_NO_FLUSH); if (ret != /* Z_STREAM_END */ Z_OK) { // doesn't finish... printf("inflate() error %d: %s\n", ret, strm.msg); return 2; } inflateEnd(&strm); printf("successful inflation: %s\n", uncompressed); return 0; }
Output:
successful inflation: 123456789012345X
Data mapping occurs without compression, but we need all 16 bytes. (There is a new line from the file to be received.) 16 + MAX_WBITS cannot even get this.
Any ideas what goes wrong? No permutation of the settings seems to go to errors.