X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/1944b2cc36c196adc4ce313d1bd6a9aae5d90024..39ed44f15f44726e08401b23b65dbbdc8ec5db8b:/deflate.c diff --git a/deflate.c b/deflate.c index 8749397..6bbceae 100644 --- a/deflate.c +++ b/deflate.c @@ -95,7 +95,7 @@ #define debug_int(x...) ( fprintf(stderr, x) ) #define debug(x) ( debug_int x ) #else -#define debug(x) +#define debug(x) ((void)0) #endif #ifdef STANDALONE @@ -1576,11 +1576,11 @@ deflate_compress_ctx *deflate_compress_new(int type) { int i; - for (i = 0; i < lenof(out->static_len1); i++) + for (i = 0; i < (int)lenof(out->static_len1); i++) out->static_len1[i] = (i < 144 ? 8 : i < 256 ? 9 : i < 280 ? 7 : 8); - for (i = 0; i < lenof(out->static_len2); i++) + for (i = 0; i < (int)lenof(out->static_len2); i++) out->static_len2[i] = 5; } hufcodes(out->static_len1, out->static_code1, lenof(out->static_code1)); @@ -2041,7 +2041,8 @@ int deflate_decompress_data(deflate_decompress_ctx *dctx, { const coderecord *rec; const unsigned char *block = (const unsigned char *)vblock; - int code, bfinal, btype, rep, dist, nlen, header, cksum; + int code, bfinal, btype, rep, dist, nlen, header; + unsigned long cksum; int error = 0; if (len == 0) { @@ -2296,14 +2297,25 @@ int deflate_decompress_data(deflate_decompress_ctx *dctx, &error); if (!dctx->currlentable) goto finished; /* error code set up by mktable */ - dctx->currdisttable = mktable(dctx->lengths + dctx->hlit, - dctx->hdist, + if (dctx->hdist == 1 && dctx->lengths[dctx->hlit] == 0) { + /* + * Special case: if the code length list for the + * backward-distance table contains a single zero + * entry, it means this block will never encode a + * backward distance at all (i.e. it's all + * literals). + */ + dctx->currdisttable = NULL; + } else { + dctx->currdisttable = mktable(dctx->lengths + dctx->hlit, + dctx->hdist, #ifdef ANALYSIS - "distance", + "distance", #endif - &error); - if (!dctx->currdisttable) - goto finished; /* error code set up by mktable */ + &error); + if (!dctx->currdisttable) + goto finished; /* error code set up by mktable */ + } freetable(&dctx->lenlentable); dctx->lenlentable = NULL; dctx->state = INBLK; @@ -2373,7 +2385,8 @@ int deflate_decompress_data(deflate_decompress_ctx *dctx, freetable(&dctx->currlentable); dctx->currlentable = NULL; } - if (dctx->currdisttable != dctx->staticdisttable) { + if (dctx->currdisttable && + dctx->currdisttable != dctx->staticdisttable) { freetable(&dctx->currdisttable); dctx->currdisttable = NULL; } @@ -2395,6 +2408,10 @@ int deflate_decompress_data(deflate_decompress_ctx *dctx, dctx->state = GOTLEN; break; case GOTLEN: + if (!dctx->currdisttable) { + error = DEFLATE_ERR_NODISTTABLE; + goto finished; + } code = huflookup(&dctx->bits, &dctx->nbits, dctx->currdisttable); debug(("recv: dist %d\n", code)); if (code == -1) @@ -2442,9 +2459,16 @@ int deflate_decompress_data(deflate_decompress_ctx *dctx, goto finished; nlen = dctx->bits & 0xFFFF; EATBITS(16); - if (dctx->uncomplen == 0) - dctx->state = OUTSIDEBLK; /* block is empty */ - else + if (dctx->uncomplen != (nlen ^ 0xFFFF)) { + error = DEFLATE_ERR_UNCOMP_HDR; + goto finished; + } + if (dctx->uncomplen == 0) {/* block is empty */ + if (dctx->lastblock) + dctx->state = END; + else + dctx->state = OUTSIDEBLK; + } else dctx->state = UNCOMP_DATA; break; case UNCOMP_DATA: @@ -2457,8 +2481,12 @@ int deflate_decompress_data(deflate_decompress_ctx *dctx, #endif emit_char(dctx, dctx->bits & 0xFF); EATBITS(8); - if (--dctx->uncomplen == 0) - dctx->state = OUTSIDEBLK; /* end of uncompressed block */ + if (--dctx->uncomplen == 0) { /* end of uncompressed block */ + if (dctx->lastblock) + dctx->state = END; + else + dctx->state = OUTSIDEBLK; + } break; case END: /* @@ -2573,6 +2601,15 @@ const char *const deflate_error_sym[DEFLATE_NUM_ERRORS] = { }; #undef A +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) +#define WINDOWS_IO +#endif + +#if defined(WINDOWS_IO) && (defined(STANDALONE) || defined(TESTMODE)) +#include +#include +#endif + #ifdef STANDALONE int main(int argc, char **argv) @@ -2648,6 +2685,14 @@ int main(int argc, char **argv) fprintf(stderr, "unable to open '%s'\n", filename); return 1; } + +#ifdef WINDOWS_IO + if(_setmode(_fileno(stdout), _O_BINARY ) == -1) + { + fprintf(stderr, "Can't set stdout to binary mode\n"); + return 1; + } +#endif do { ret = fread(buf, 1, sizeof(buf), fp); @@ -2736,6 +2781,14 @@ int main(int argc, char **argv) chandle = deflate_compress_new(DEFLATE_TYPE_ZLIB); dhandle = deflate_decompress_new(DEFLATE_TYPE_ZLIB); + +#ifdef WINDOWS_IO + if(_setmode(_fileno(stdout), _O_BINARY ) == -1) + { + fprintf(stderr, "Can't set stdout to binary mode\n"); + return 1; + } +#endif do { ret = fread(buf, 1, sizeof(buf), fp);