diff --git a/src/compression.c b/src/compression.c index 48ac305..cf39232 100644 --- a/src/compression.c +++ b/src/compression.c @@ -141,7 +141,10 @@ static MOBI_RET mobi_decompress_huffman_internal(MOBIBuffer *buf_out, MOBIBuffer if (!(t1 & 0x80)) { /* get offset from mincode, maxcode tables */ while (code < huffcdic->mincode_table[code_length]) { - code_length++; + if (++code_length >= HUFF_CODETABLE_SIZE) { + debug_print("Wrong offset to mincode table: %hhu\n", code_length); + return MOBI_DATA_CORRUPT; + } } maxcode = huffcdic->maxcode_table[code_length]; } diff --git a/src/compression.h b/src/compression.h index e18b3c7..59e116e 100644 --- a/src/compression.h +++ b/src/compression.h @@ -20,6 +20,7 @@ /* FIXME: what is the reasonable value? */ #define MOBI_HUFFMAN_MAXDEPTH 20 /**< Maximal recursion level for huffman decompression routine */ +#define HUFF_CODETABLE_SIZE 33 /**< Size of min- and maxcode tables */ /** @@ -30,8 +31,8 @@ typedef struct { size_t index_read; /**< Number of indices parsed, used by parser */ size_t code_length; /**< Code length value stored in CDIC record header */ uint32_t table1[256]; /**< Table of big-endian indices from HUFF record data1 */ - uint32_t mincode_table[33]; /**< Table of big-endian mincodes from HUFF record data2 */ - uint32_t maxcode_table[33]; /**< Table of big-endian maxcodes from HUFF record data2 */ + uint32_t mincode_table[HUFF_CODETABLE_SIZE]; /**< Table of big-endian mincodes from HUFF record data2 */ + uint32_t maxcode_table[HUFF_CODETABLE_SIZE]; /**< Table of big-endian maxcodes from HUFF record data2 */ uint16_t *symbol_offsets; /**< Index of symbol offsets parsed from CDIC records (index_count entries) */ unsigned char **symbols; /**< Array of pointers to start of symbols data in each CDIC record (index = number of CDIC record) */ } MOBIHuffCdic; diff --git a/src/read.c b/src/read.c index b90fcf3..0d2d9e4 100644 --- a/src/read.c +++ b/src/read.c @@ -589,7 +589,7 @@ MOBI_RET mobi_parse_huff(MOBIHuffCdic *huffcdic, const MOBIPdbRecord *record) { /* read 32 mincode-maxcode pairs from data2 big-endian */ huffcdic->mincode_table[0] = 0; huffcdic->maxcode_table[0] = 0xFFFFFFFF; - for (int i = 1; i < 33; i++) { + for (int i = 1; i < HUFF_CODETABLE_SIZE; i++) { const uint32_t mincode = mobi_buffer_get32(buf); const uint32_t maxcode = mobi_buffer_get32(buf); huffcdic->mincode_table[i] = mincode << (32 - i);