# HG changeset patch # User Matti Hamalainen # Date 1425257797 -7200 # Node ID b20922f4746fed86dc744332647fb7a1e2dce48c # Parent 01114659bdd356299adba2163c7061c29df2d92b Comments, cleanups. diff -r 01114659bdd3 -r b20922f4746f src/dmzlib.c --- a/src/dmzlib.c Mon Mar 02 02:12:47 2015 +0200 +++ b/src/dmzlib.c Mon Mar 02 02:56:37 2015 +0200 @@ -332,6 +332,7 @@ ctx->zout = zout; return DMERR_OK; } + z -= 257; len = dm_zlib_length_base[z]; @@ -384,31 +385,44 @@ static int dmZLibComputeHuffmanCodes(DMZLibContext * ctx) { - DMZHuffmanContext z_codelength; - Uint8 codeLengths[288 + 32 + 137]; // padding for maximum single op + DMZHuffmanContext codeLengthCtx; Uint8 codeLengthSizes[DM_ZLIB_NCODELENGTH_SIZES]; + Uint8 codeLengths[288 + 32 + 137]; // padding for maximum single op int i, n, ret; - int hlit = dmZReceive(ctx, 5) + 257; - int hdist = dmZReceive(ctx, 5) + 1; - int hclen = dmZReceive(ctx, 4) + 4; + // Get table sizes + int hlit = dmZReceive(ctx, 5) + 257; // 288 = X + int hdist = dmZReceive(ctx, 5) + 1; // 32 = X + int hclen = dmZReceive(ctx, 4) + 4; // 19 = DM_ZLIB_NCODELENGTH_SIZES + if (hlit > 286 || hdist > 30) + { + return dmErrorDBG(DMERR_INVALID_DATA, + "Too many Huffman length or distance symbols (%d, %d)", + hlit, hdist); + } + + // Get lengths table (uninitialized entries should be set to 0) memset(codeLengthSizes, 0, sizeof(codeLengthSizes)); - for (i = 0; i < hclen; i++) { int s = dmZReceive(ctx, 3); codeLengthSizes[dm_zlib_length_dezigzag[i]] = (Uint8) s; } - if ((ret = dmZLibBuildHuffmanTables(&z_codelength, codeLengthSizes, 19)) != DMERR_OK) - return ret; + // Inflate the code lengths table + if ((ret = dmZLibBuildHuffmanTables(&codeLengthCtx, + codeLengthSizes, DM_ZLIB_NCODELENGTH_SIZES)) != DMERR_OK) + { + return dmErrorDBG(ret, + "Invalid code lengths set.\n"); + } n = 0; while (n < hlit + hdist) { int c; - if ((ret = dmZLibHuffmanDecode(ctx, &z_codelength, &c)) != DMERR_OK) + if ((ret = dmZLibHuffmanDecode(ctx, &codeLengthCtx, &c)) != DMERR_OK) return ret; DMZLIB_ASSERT(c >= 0 && c < DM_ZLIB_NCODELENGTH_SIZES); @@ -418,31 +432,43 @@ else if (c == 16) { - c = dmZReceive(ctx, 2) + 3; - memset(codeLengths + n, codeLengths[n - 1], c); - n += c; + int bv = dmZReceive(ctx, 2) + 3; + if (n == 0) + { + return dmErrorDBG(DMERR_INVALID_DATA, + "Invalid bit length repeat.\n"); + } + memset(codeLengths + n, codeLengths[n - 1], bv); + n += bv; } else if (c == 17) { - c = dmZReceive(ctx, 3) + 3; - memset(codeLengths + n, 0, c); - n += c; + int bv = dmZReceive(ctx, 3) + 3; + memset(codeLengths + n, 0, bv); + n += bv; } else { - c = dmZReceive(ctx, 7) + 11; - memset(codeLengths + n, 0, c); - n += c; + int bv = dmZReceive(ctx, 7) + 11; + memset(codeLengths + n, 0, bv); + n += bv; } } + if (codeLengths[256] == 0) + { + return dmErrorDBG(DMERR_DATA_ERROR, + "Invalid code -- missing end-of-block.\n"); + } + if (n != hlit + hdist) { return dmErrorDBG(DMERR_DATA_ERROR, "Bad huffman codelengths.\n"); } + // Build the code tables if ((ret = dmZLibBuildHuffmanTables(&ctx->zlength, codeLengths, hlit)) != DMERR_OK) return ret; diff -r 01114659bdd3 -r b20922f4746f src/dmzlib.h --- a/src/dmzlib.h Mon Mar 02 02:12:47 2015 +0200 +++ b/src/dmzlib.h Mon Mar 02 02:56:37 2015 +0200 @@ -21,6 +21,7 @@ #define DM_ZLIB_HUFF_CODES (288) #define DM_ZLIB_HUFF_DIST (32) + typedef struct { BOOL initialized;