X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/3d88e64dfcf5dc0fd361ce0c504c67a9196ce44c..33f07e9636e80bb17f25f97145ca2e0eb262db30:/sshzlib.c diff --git a/sshzlib.c b/sshzlib.c index a98d96c6..4e70d282 100644 --- a/sshzlib.c +++ b/sshzlib.c @@ -602,6 +602,8 @@ void zlib_compress_cleanup(void *handle) { struct LZ77Context *ectx = (struct LZ77Context *)handle; sfree(ectx->userdata); + sfree(ectx->ictx); + sfree(ectx); } /* @@ -963,13 +965,15 @@ void *zlib_decompress_init(void) void zlib_decompress_cleanup(void *handle) { struct zlib_decompress_ctx *dctx = (struct zlib_decompress_ctx *)handle; - + if (dctx->currlentable && dctx->currlentable != dctx->staticlentable) zlib_freetable(&dctx->currlentable); if (dctx->currdisttable && dctx->currdisttable != dctx->staticdisttable) zlib_freetable(&dctx->currdisttable); if (dctx->lenlentable) zlib_freetable(&dctx->lenlentable); + zlib_freetable(&dctx->staticlentable); + zlib_freetable(&dctx->staticdisttable); sfree(dctx); } @@ -992,6 +996,16 @@ static int zlib_huflookup(unsigned long *bitsp, int *nbitsp, *nbitsp = nbits; return ent->code; } + + if (!tab) { + /* + * There was a missing entry in the table, presumably + * due to an invalid Huffman table description, and the + * subsequent data has attempted to use the missing + * entry. Return a decoding failure. + */ + return -2; + } } } @@ -1099,6 +1113,8 @@ int zlib_decompress_block(void *handle, unsigned char *block, int len, zlib_huflookup(&dctx->bits, &dctx->nbits, dctx->lenlentable); if (code == -1) goto finished; + if (code == -2) + goto decode_error; if (code < 16) dctx->lengths[dctx->lenptr++] = code; else { @@ -1128,6 +1144,8 @@ int zlib_decompress_block(void *handle, unsigned char *block, int len, zlib_huflookup(&dctx->bits, &dctx->nbits, dctx->currlentable); if (code == -1) goto finished; + if (code == -2) + goto decode_error; if (code < 256) zlib_emit_char(dctx, code); else if (code == 256) { @@ -1160,6 +1178,8 @@ int zlib_decompress_block(void *handle, unsigned char *block, int len, dctx->currdisttable); if (code == -1) goto finished; + if (code == -2) + goto decode_error; dctx->state = GOTDISTSYM; dctx->sym = code; break; @@ -1213,8 +1233,13 @@ int zlib_decompress_block(void *handle, unsigned char *block, int len, finished: *outblock = dctx->outblk; *outlen = dctx->outlen; - return 1; + + decode_error: + sfree(dctx->outblk); + *outblock = dctx->outblk = NULL; + *outlen = 0; + return 0; } const struct ssh_compress ssh_zlib = {