From d01c71c4ad7d049df51c7192c938d3d6756293c5 Mon Sep 17 00:00:00 2001 From: Zoltan Szabadka Date: Wed, 8 Jan 2014 12:34:35 +0100 Subject: [PATCH] Fix -Wconversion compiler warnings in the brotli decoder. --- dec/bit_reader.c | 5 +- dec/bit_reader.h | 35 ++++---- dec/decode.c | 198 +++++++++++++++++++++++++--------------------- dec/huffman.c | 2 +- dec/safe_malloc.h | 2 +- dec/streams.c | 4 +- 6 files changed, 135 insertions(+), 111 deletions(-) diff --git a/dec/bit_reader.c b/dec/bit_reader.c index d56c7b8..25e33e3 100644 --- a/dec/bit_reader.c +++ b/dec/bit_reader.c @@ -28,11 +28,12 @@ int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input) { size_t i; assert(br != NULL); + br->buf_ptr_ = br->buf_; br->input_ = input; br->val_ = 0; br->pos_ = 0; br->bit_pos_ = 0; - br->end_pos_ = 0; + br->bits_left_ = 64; br->eos_ = 0; if (!BrotliReadMoreInput(br)) { return 0; @@ -41,7 +42,7 @@ int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input) { br->val_ |= ((uint64_t)br->buf_[br->pos_]) << (8 * i); ++br->pos_; } - return (br->end_pos_ > 0); + return (br->bits_left_ > 64); } #if defined(__cplusplus) || defined(c_plusplus) diff --git a/dec/bit_reader.h b/dec/bit_reader.h index 00c2ac9..551cc14 100644 --- a/dec/bit_reader.h +++ b/dec/bit_reader.h @@ -42,12 +42,13 @@ typedef struct { /* Input byte buffer, consist of a ringbuffer and a "slack" region where */ /* bytes from the start of the ringbuffer are copied. */ uint8_t buf_[BROTLI_IBUF_SIZE]; - BrotliInput input_; /* input callback */ - uint64_t val_; /* pre-fetched bits */ - size_t pos_; /* byte position in stream */ - int bit_pos_; /* current bit-reading position in val_ */ - size_t end_pos_; /* current end position in stream */ - int eos_; /* input stream is finished */ + uint8_t* buf_ptr_; /* next input will write here */ + BrotliInput input_; /* input callback */ + uint64_t val_; /* pre-fetched bits */ + uint32_t pos_; /* byte position in stream */ + uint32_t bit_pos_; /* current bit-reading position in val_ */ + uint32_t bits_left_; /* how many valid bits left */ + int eos_; /* input stream is finished */ } BrotliBitReader; int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input); @@ -59,9 +60,10 @@ static BROTLI_INLINE uint32_t BrotliPrefetchBits(BrotliBitReader* const br) { /* For jumping over a number of bits in the bit stream when accessed with */ /* BrotliPrefetchBits and BrotliFillBitWindow. */ -static BROTLI_INLINE void BrotliSetBitPos(BrotliBitReader* const br, int val) { +static BROTLI_INLINE void BrotliSetBitPos(BrotliBitReader* const br, + uint32_t val) { #ifdef BROTLI_DECODE_DEBUG - int n_bits = val - br->bit_pos_; + uint32_t n_bits = val - br->bit_pos_; const uint32_t bval = (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits]; printf("[BrotliReadBits] %010ld %2d val: %6x\n", (br->pos_ << 3) + br->bit_pos_ - 64, n_bits, bval); @@ -76,6 +78,7 @@ static BROTLI_INLINE void ShiftBytes(BrotliBitReader* const br) { br->val_ |= ((uint64_t)br->buf_[br->pos_ & BROTLI_IBUF_MASK]) << 56; ++br->pos_; br->bit_pos_ -= 8; + br->bits_left_ -= 8; } } @@ -92,12 +95,12 @@ static BROTLI_INLINE void ShiftBytes(BrotliBitReader* const br) { every 32 bytes of input is read. */ static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) { - if (br->pos_ + 32 < br->end_pos_) { + if (br->bits_left_ > 320) { return 1; } else if (br->eos_) { - return (br->pos_ << 3) + br->bit_pos_ <= (br->end_pos_ << 3) + 64; + return br->bit_pos_ <= br->bits_left_; } else { - uint8_t* dst = br->buf_ + (br->end_pos_ & BROTLI_IBUF_MASK); + uint8_t* dst = br->buf_ptr_; int bytes_read = BrotliRead(br->input_, dst, BROTLI_READ_SIZE); if (bytes_read < 0) { return 0; @@ -124,8 +127,11 @@ static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) { #else memcpy(br->buf_ + (BROTLI_READ_SIZE << 1), br->buf_, 32); #endif + br->buf_ptr_ = br->buf_ + BROTLI_READ_SIZE; + } else { + br->buf_ptr_ = br->buf_; } - br->end_pos_ += bytes_read; + br->bits_left_ += ((uint32_t)bytes_read << 3); return 1; } } @@ -135,12 +141,13 @@ static BROTLI_INLINE void BrotliFillBitWindow(BrotliBitReader* const br) { if (br->bit_pos_ >= 40) { #if (defined(__x86_64__) || defined(_M_X64)) br->val_ >>= 40; - br->bit_pos_ -= 40; /* The expression below needs a little-endian arch to work correctly. */ /* This gives a large speedup for decoding speed. */ br->val_ |= *(const uint64_t*)( br->buf_ + (br->pos_ & BROTLI_IBUF_MASK)) << 24; br->pos_ += 5; + br->bit_pos_ -= 40; + br->bits_left_ -= 40; #else ShiftBytes(br); #endif @@ -158,7 +165,7 @@ static BROTLI_INLINE uint32_t BrotliReadBits( printf("[BrotliReadBits] %010ld %2d val: %6x\n", (br->pos_ << 3) + br->bit_pos_ - 64, n_bits, val); #endif - br->bit_pos_ += n_bits; + br->bit_pos_ += (uint32_t)n_bits; return val; } diff --git a/dec/decode.c b/dec/decode.c index df2e1f9..a8e41ab 100644 --- a/dec/decode.c +++ b/dec/decode.c @@ -38,8 +38,8 @@ extern "C" { #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) #endif -static const int kDefaultCodeLength = 8; -static const int kCodeLengthRepeatCode = 16; +static const uint8_t kDefaultCodeLength = 8; +static const uint8_t kCodeLengthRepeatCode = 16; static const int kNumLiteralCodes = 256; static const int kNumInsertAndCopyCodes = 704; static const int kNumBlockLengthCodes = 26; @@ -62,7 +62,7 @@ static const int kDistanceShortCodeValueOffset[NUM_DISTANCE_SHORT_CODES] = { static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) { if (BrotliReadBits(br, 1)) { - return 17 + BrotliReadBits(br, 3); + return 17 + (int)BrotliReadBits(br, 3); } else { return 16; } @@ -71,35 +71,35 @@ static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) { /* Decodes a number in the range [0..255], by reading 1 - 11 bits. */ static BROTLI_INLINE int DecodeVarLenUint8(BrotliBitReader* br) { if (BrotliReadBits(br, 1)) { - int nbits = BrotliReadBits(br, 3); + int nbits = (int)BrotliReadBits(br, 3); if (nbits == 0) { return 1; } else { - return BrotliReadBits(br, nbits) + (1 << nbits); + return (int)BrotliReadBits(br, nbits) + (1 << nbits); } } return 0; } static void DecodeMetaBlockLength(BrotliBitReader* br, - size_t* meta_block_length, + int* meta_block_length, int* input_end, int* is_uncompressed) { int size_nibbles; int i; - *input_end = BrotliReadBits(br, 1); + *input_end = (int)BrotliReadBits(br, 1); *meta_block_length = 0; *is_uncompressed = 0; if (*input_end && BrotliReadBits(br, 1)) { return; } - size_nibbles = BrotliReadBits(br, 2) + 4; + size_nibbles = (int)BrotliReadBits(br, 2) + 4; for (i = 0; i < size_nibbles; ++i) { - *meta_block_length |= BrotliReadBits(br, 4) << (i * 4); + *meta_block_length |= (int)BrotliReadBits(br, 4) << (i * 4); } ++(*meta_block_length); if (!*input_end) { - *is_uncompressed = BrotliReadBits(br, 1); + *is_uncompressed = (int)BrotliReadBits(br, 1); } } @@ -107,9 +107,9 @@ static void DecodeMetaBlockLength(BrotliBitReader* br, static BROTLI_INLINE int ReadSymbol(const HuffmanTree* tree, BrotliBitReader* br) { uint32_t bits; - int bitpos; + uint32_t bitpos; int lut_ix; - int lut_bits; + uint8_t lut_bits; const HuffmanTreeNode* node = tree->root_; BrotliFillBitWindow(br); bits = BrotliPrefetchBits(br); @@ -147,9 +147,9 @@ static int ReadHuffmanCodeLengths( BrotliBitReader* br) { int ok = 0; int symbol; - int prev_code_len = kDefaultCodeLength; + uint8_t prev_code_len = kDefaultCodeLength; int repeat = 0; - int repeat_length = 0; + uint8_t repeat_length = 0; int space = 32768; HuffmanTree tree; @@ -167,12 +167,12 @@ static int ReadHuffmanCodeLengths( symbol = 0; while (symbol + repeat < num_symbols && space > 0) { - int code_len; + uint8_t code_len; if (!BrotliReadMoreInput(br)) { printf("[ReadHuffmanCodeLengths] Unexpected end of input.\n"); goto End; } - code_len = ReadSymbol(&tree, br); + code_len = (uint8_t)ReadSymbol(&tree, br); BROTLI_LOG_UINT(symbol); BROTLI_LOG_UINT(repeat); BROTLI_LOG_UINT(repeat_length); @@ -198,7 +198,7 @@ static int ReadHuffmanCodeLengths( repeat -= 2; repeat <<= extra_bits; } - repeat += BrotliReadBits(br, extra_bits) + 3; + repeat += (int)BrotliReadBits(br, extra_bits) + 3; if (repeat + symbol > num_symbols) { goto End; } @@ -250,21 +250,22 @@ static int ReadHuffmanCode(int alphabet_size, /* simple_code_or_skip is used as follows: 1 for simple code; 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ - simple_code_or_skip = BrotliReadBits(br, 2); + simple_code_or_skip = (int)BrotliReadBits(br, 2); BROTLI_LOG_UINT(simple_code_or_skip); - if (simple_code_or_skip == 1) { /* Read symbols, codes & code lengths directly. */ + if (simple_code_or_skip == 1) { + /* Read symbols, codes & code lengths directly. */ int i; int max_bits_counter = alphabet_size - 1; int max_bits = 0; int symbols[4] = { 0 }; - const int num_symbols = BrotliReadBits(br, 2) + 1; + const int num_symbols = (int)BrotliReadBits(br, 2) + 1; while (max_bits_counter) { max_bits_counter >>= 1; ++max_bits; } - memset(code_lengths, 0, alphabet_size); + memset(code_lengths, 0, (size_t)alphabet_size); for (i = 0; i < num_symbols; ++i) { - symbols[i] = BrotliReadBits(br, max_bits) % alphabet_size; + symbols[i] = (int)BrotliReadBits(br, max_bits) % alphabet_size; code_lengths[symbols[i]] = 2; } code_lengths[symbols[0]] = 1; @@ -292,13 +293,13 @@ static int ReadHuffmanCode(int alphabet_size, for (i = simple_code_or_skip; i < CODE_LENGTH_CODES && space > 0; ++i) { int code_len_idx = kCodeLengthCodeOrder[i]; - int v = BrotliReadBits(br, 2); + uint8_t v = (uint8_t)BrotliReadBits(br, 2); if (v == 1) { - v = BrotliReadBits(br, 1); + v = (uint8_t)BrotliReadBits(br, 1); if (v == 0) { v = 2; } else { - v = BrotliReadBits(br, 1); + v = (uint8_t)BrotliReadBits(br, 1); if (v == 0) { v = 1; } else { @@ -331,7 +332,7 @@ static int ReadHuffmanCode(int alphabet_size, static int ReadCopyDistance(const HuffmanTree* tree, int num_direct_codes, int postfix_bits, - uint32_t postfix_mask, + int postfix_mask, BrotliBitReader* br) { int code; int nbits; @@ -347,7 +348,7 @@ static int ReadCopyDistance(const HuffmanTree* tree, nbits = (code >> 1) + 1; offset = ((2 + (code & 1)) << nbits) - 4; return (num_direct_codes + - ((offset + BrotliReadBits(br, nbits)) << postfix_bits) + + ((offset + (int)BrotliReadBits(br, nbits)) << postfix_bits) + postfix); } @@ -356,7 +357,7 @@ static int ReadBlockLength(const HuffmanTree* tree, BrotliBitReader* br) { int nbits; code = ReadSymbol(tree, br); nbits = kBlockLengthPrefixCode[code].nbits; - return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits); + return kBlockLengthPrefixCode[code].offset + (int)BrotliReadBits(br, nbits); } static void ReadInsertAndCopy(const HuffmanTree* tree, @@ -383,17 +384,17 @@ static void ReadInsertAndCopy(const HuffmanTree* tree, *insert_len = kInsertLengthPrefixCode[insert_code].offset; insert_extra_bits = kInsertLengthPrefixCode[insert_code].nbits; if (insert_extra_bits > 0) { - *insert_len += BrotliReadBits(br, insert_extra_bits); + *insert_len += (int)BrotliReadBits(br, insert_extra_bits); } *copy_len = kCopyLengthPrefixCode[copy_code].offset; copy_extra_bits = kCopyLengthPrefixCode[copy_code].nbits; if (copy_extra_bits > 0) { - *copy_len += BrotliReadBits(br, copy_extra_bits); + *copy_len += (int)BrotliReadBits(br, copy_extra_bits); } } -static size_t TranslateShortCodes(int code, int* ringbuffer, size_t index) { - size_t val; +static int TranslateShortCodes(int code, int* ringbuffer, int index) { + int val; if (code < NUM_DISTANCE_SHORT_CODES) { index += kDistanceShortCodeIndexOffset[code]; index &= 3; @@ -415,7 +416,7 @@ static void InverseMoveToFrontTransform(uint8_t* v, int v_len) { uint8_t mtf[256]; int i; for (i = 0; i < 256; ++i) { - mtf[i] = i; + mtf[i] = (uint8_t)i; } for (i = 0; i < v_len; ++i) { uint8_t index = v[i]; @@ -436,7 +437,7 @@ static void HuffmanTreeGroupInit(HuffmanTreeGroup* group, int alphabet_size, int i; group->alphabet_size = alphabet_size; group->num_htrees = ntrees; - group->htrees = (HuffmanTree*)malloc(sizeof(HuffmanTree) * ntrees); + group->htrees = (HuffmanTree*)malloc(sizeof(HuffmanTree) * (size_t)ntrees); for (i = 0; i < ntrees; ++i) { group->htrees[i].root_ = NULL; } @@ -477,22 +478,22 @@ static int DecodeContextMap(int context_map_size, BROTLI_LOG_UINT(context_map_size); BROTLI_LOG_UINT(*num_htrees); - *context_map = (uint8_t*)malloc(context_map_size); + *context_map = (uint8_t*)malloc((size_t)context_map_size); if (*context_map == 0) { return 0; } if (*num_htrees <= 1) { - memset(*context_map, 0, context_map_size); + memset(*context_map, 0, (size_t)context_map_size); return 1; } { HuffmanTree tree_index_htree; - int use_rle_for_zeros = BrotliReadBits(br, 1); + int use_rle_for_zeros = (int)BrotliReadBits(br, 1); int max_run_length_prefix = 0; int i; if (use_rle_for_zeros) { - max_run_length_prefix = BrotliReadBits(br, 4) + 1; + max_run_length_prefix = (int)BrotliReadBits(br, 4) + 1; } if (!ReadHuffmanCode(*num_htrees + max_run_length_prefix, &tree_index_htree, br)) { @@ -510,7 +511,7 @@ static int DecodeContextMap(int context_map_size, (*context_map)[i] = 0; ++i; } else if (code <= max_run_length_prefix) { - int reps = 1 + (1 << code) + BrotliReadBits(br, code); + int reps = 1 + (1 << code) + (int)BrotliReadBits(br, code); while (--reps) { if (i >= context_map_size) { ok = 0; @@ -520,7 +521,7 @@ static int DecodeContextMap(int context_map_size, ++i; } } else { - (*context_map)[i] = code - max_run_length_prefix; + (*context_map)[i] = (uint8_t)(code - max_run_length_prefix); ++i; } } @@ -538,10 +539,10 @@ static BROTLI_INLINE void DecodeBlockType(const int max_block_type, int tree_type, int* block_types, int* ringbuffers, - size_t* indexes, + int* indexes, BrotliBitReader* br) { int* ringbuffer = ringbuffers + tree_type * 2; - size_t* index = indexes + tree_type; + int* index = indexes + tree_type; int type_code = ReadSymbol(trees + tree_type, br); int block_type; if (type_code == 0) { @@ -595,7 +596,7 @@ static BROTLI_INLINE void IncrementalCopyFastPath( if (src < dst) { while (dst - src < 8) { UNALIGNED_COPY64(dst, src); - len -= dst - src; + len -= (int)(dst - src); dst += dst - src; } } @@ -613,7 +614,7 @@ int BrotliDecompressedSize(size_t encoded_size, BrotliMemInput memin; BrotliInput input = BrotliInitMemInput(encoded_buffer, encoded_size, &memin); BrotliBitReader br; - size_t meta_block_len; + int meta_block_len; int input_end; int is_uncompressed; if (!BrotliInitBitReader(&br, input)) { @@ -624,7 +625,7 @@ int BrotliDecompressedSize(size_t encoded_size, if (!input_end) { return 0; } - *decoded_size = meta_block_len; + *decoded_size = (size_t)meta_block_len; return 1; } @@ -644,18 +645,19 @@ int BrotliDecompressBuffer(size_t encoded_size, int BrotliDecompress(BrotliInput input, BrotliOutput output) { int ok = 1; int i; - size_t pos = 0; + int pos = 0; int input_end = 0; int window_bits = 0; - size_t max_backward_distance; - size_t ringbuffer_size; - size_t ringbuffer_mask; + int max_backward_distance; + int max_distance = 0; + int ringbuffer_size; + int ringbuffer_mask; uint8_t* ringbuffer; uint8_t* ringbuffer_end; /* This ring buffer holds a few past copy distances that will be used by */ /* some special distance codes. */ int dist_rb[4] = { 16, 15, 11, 4 }; - size_t dist_rb_idx = 0; + int dist_rb_idx = 0; /* The previous 2 bytes used for context. */ uint8_t prev_byte1 = 0; uint8_t prev_byte2 = 0; @@ -674,32 +676,31 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { /* Decode window size. */ window_bits = DecodeWindowBits(&br); - max_backward_distance = (1ULL << window_bits) - 16; + max_backward_distance = (1 << window_bits) - 16; - ringbuffer_size = 1ULL << window_bits; + ringbuffer_size = 1 << window_bits; ringbuffer_mask = ringbuffer_size - 1; - ringbuffer = (uint8_t*)malloc(ringbuffer_size + - kRingBufferWriteAheadSlack + - kMaxDictionaryWordLength); + ringbuffer = (uint8_t*)malloc((size_t)(ringbuffer_size + + kRingBufferWriteAheadSlack + + kMaxDictionaryWordLength)); if (!ringbuffer) { ok = 0; } ringbuffer_end = ringbuffer + ringbuffer_size; while (!input_end && ok) { - size_t meta_block_len = 0; - size_t meta_block_end_pos; + int meta_block_remaining_len = 0; int is_uncompressed; - uint32_t block_length[3] = { 1 << 28, 1 << 28, 1 << 28 }; + int block_length[3] = { 1 << 28, 1 << 28, 1 << 28 }; int block_type[3] = { 0 }; int num_block_types[3] = { 1, 1, 1 }; int block_type_rb[6] = { 0, 1, 0, 1, 0, 1 }; - size_t block_type_rb_index[3] = { 0 }; + int block_type_rb_index[3] = { 0 }; HuffmanTree block_type_trees[3]; HuffmanTree block_len_trees[3]; int distance_postfix_bits; int num_direct_distance_codes; - uint32_t distance_postfix_mask; + int distance_postfix_mask; int num_distance_codes; uint8_t* context_map = NULL; uint8_t* context_modes = NULL; @@ -729,22 +730,24 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { goto End; } BROTLI_LOG_UINT(pos); - DecodeMetaBlockLength(&br, &meta_block_len, &input_end, &is_uncompressed); - BROTLI_LOG_UINT(meta_block_len); - if (meta_block_len == 0) { + DecodeMetaBlockLength(&br, &meta_block_remaining_len, + &input_end, &is_uncompressed); + BROTLI_LOG_UINT(meta_block_remaining_len); + if (meta_block_remaining_len == 0) { goto End; } - meta_block_end_pos = pos + meta_block_len; if (is_uncompressed) { - BrotliSetBitPos(&br, (br.bit_pos_ + 7) & ~7); - for (; pos < meta_block_end_pos; ++pos) { - ringbuffer[pos & ringbuffer_mask] = BrotliReadBits(&br, 8); + BrotliSetBitPos(&br, (br.bit_pos_ + 7) & (uint32_t)(~7UL)); + while (meta_block_remaining_len) { + ringbuffer[pos & ringbuffer_mask] = (uint8_t)BrotliReadBits(&br, 8); if ((pos & ringbuffer_mask) == ringbuffer_mask) { - if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) { + if (BrotliWrite(output, ringbuffer, (size_t)ringbuffer_size) < 0) { ok = 0; goto End; } } + ++pos; + --meta_block_remaining_len; } goto End; } @@ -776,19 +779,19 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { ok = 0; goto End; } - distance_postfix_bits = BrotliReadBits(&br, 2); + distance_postfix_bits = (int)BrotliReadBits(&br, 2); num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES + - (BrotliReadBits(&br, 4) << distance_postfix_bits); + ((int)BrotliReadBits(&br, 4) << distance_postfix_bits); distance_postfix_mask = (1 << distance_postfix_bits) - 1; num_distance_codes = (num_direct_distance_codes + (48 << distance_postfix_bits)); - context_modes = (uint8_t*)malloc(num_block_types[0]); + context_modes = (uint8_t*)malloc((size_t)num_block_types[0]); if (context_modes == 0) { ok = 0; goto End; } for (i = 0; i < num_block_types[0]; ++i) { - context_modes[i] = BrotliReadBits(&br, 2) << 1; + context_modes[i] = (uint8_t)(BrotliReadBits(&br, 2) << 1); BROTLI_LOG_ARRAY_INDEX(context_modes, i); } BROTLI_LOG_UINT(num_direct_distance_codes); @@ -820,12 +823,11 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { context_lookup_offset1 = kContextLookupOffsets[context_mode]; context_lookup_offset2 = kContextLookupOffsets[context_mode + 1]; - while (pos < meta_block_end_pos) { + while (meta_block_remaining_len > 0) { int insert_length; int copy_length; int distance_code; - size_t distance; - size_t max_distance; + int distance; uint8_t context; int j; const uint8_t* copy_src; @@ -870,19 +872,21 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { literal_htree_index = context_map_slice[context]; --block_length[0]; prev_byte2 = prev_byte1; - prev_byte1 = ReadSymbol(&hgroup[0].htrees[literal_htree_index], &br); + prev_byte1 = (uint8_t)ReadSymbol(&hgroup[0].htrees[literal_htree_index], + &br); ringbuffer[pos & ringbuffer_mask] = prev_byte1; BROTLI_LOG_UINT(literal_htree_index); BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos & ringbuffer_mask); if ((pos & ringbuffer_mask) == ringbuffer_mask) { - if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) { + if (BrotliWrite(output, ringbuffer, (size_t)ringbuffer_size) < 0) { ok = 0; goto End; } } ++pos; } - if (pos == meta_block_end_pos) break; + meta_block_remaining_len -= insert_length; + if (meta_block_remaining_len <= 0) break; if (distance_code < 0) { uint8_t context; @@ -896,12 +900,12 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { block_type_trees, 2, block_type, block_type_rb, block_type_rb_index, &br); block_length[2] = ReadBlockLength(&block_len_trees[2], &br); - dist_htree_index = block_type[2]; + dist_htree_index = (uint8_t)block_type[2]; dist_context_offset = block_type[2] << kDistanceContextBits; dist_context_map_slice = dist_context_map + dist_context_offset; } --block_length[2]; - context = copy_length > 4 ? 3 : copy_length - 2; + context = (uint8_t)(copy_length > 4 ? 3 : copy_length - 2); dist_htree_index = dist_context_map_slice[context]; distance_code = ReadCopyDistance(&hgroup[2].htrees[dist_htree_index], num_direct_distance_codes, @@ -913,30 +917,36 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { /* Convert the distance code to the actual distance by possibly looking */ /* up past distnaces from the ringbuffer. */ distance = TranslateShortCodes(distance_code, dist_rb, dist_rb_idx); + if (distance < 0) { + ok = 0; + goto End; + } if (distance_code > 0) { dist_rb[dist_rb_idx & 3] = distance; ++dist_rb_idx; } BROTLI_LOG_UINT(distance); - max_distance = max_backward_distance; - if (pos < max_distance) { + if (pos < max_backward_distance && + max_distance != max_backward_distance) { max_distance = pos; + } else { + max_distance = max_backward_distance; } copy_dst = &ringbuffer[pos & ringbuffer_mask]; if (distance > max_distance) { - printf("Invalid backward reference. pos: %lu distance: %d " - "len: %d end: %lu\n", (unsigned long)pos, (int)distance, - copy_length, (unsigned long)meta_block_end_pos); + printf("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", pos, distance, copy_length, + meta_block_remaining_len); ok = 0; goto End; } else { - if (pos + copy_length > meta_block_end_pos) { - printf("Invalid backward reference. pos: %lu distance: %d " - "len: %d end: %lu\n", (unsigned long)pos, (int)distance, - copy_length, (unsigned long)meta_block_end_pos); + if (copy_length > meta_block_remaining_len) { + printf("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", pos, distance, copy_length, + meta_block_remaining_len); ok = 0; goto End; } @@ -953,6 +963,7 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { IncrementalCopyFastPath(copy_dst, copy_src, copy_length); } pos += copy_length; + meta_block_remaining_len -= copy_length; copy_length = 0; } #endif @@ -961,12 +972,13 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { ringbuffer[pos & ringbuffer_mask] = ringbuffer[(pos - distance) & ringbuffer_mask]; if ((pos & ringbuffer_mask) == ringbuffer_mask) { - if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) { + if (BrotliWrite(output, ringbuffer, (size_t)ringbuffer_size) < 0) { ok = 0; goto End; } } ++pos; + --meta_block_remaining_len; } } @@ -976,6 +988,10 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { prev_byte1 = ringbuffer[(pos - 1) & ringbuffer_mask]; prev_byte2 = ringbuffer[(pos - 2) & ringbuffer_mask]; } + + /* Protect pos from overflow, wrap it around at every GB of input data */ + pos &= 0x3fffffff; + End: if (context_modes != 0) { free(context_modes); @@ -994,7 +1010,7 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) { } if (ringbuffer != 0) { - if (BrotliWrite(output, ringbuffer, pos & ringbuffer_mask) < 0) { + if (BrotliWrite(output, ringbuffer, (size_t)(pos & ringbuffer_mask)) < 0) { ok = 0; } free(ringbuffer); diff --git a/dec/huffman.c b/dec/huffman.c index a25f351..20e6223 100644 --- a/dec/huffman.c +++ b/dec/huffman.c @@ -163,7 +163,7 @@ static int TreeAddSymbol(HuffmanTree* const tree, --i; idx = base_code | (i << code_length); tree->lut_symbol_[idx] = (int16_t)symbol; - tree->lut_bits_[idx] = code_length; + tree->lut_bits_[idx] = (uint8_t)code_length; } while (i > 0); } else { base_code = ReverseBitsShort((code >> (code_length - HUFF_LUT_BITS)), diff --git a/dec/safe_malloc.h b/dec/safe_malloc.h index 2a6268f..9a73b0e 100644 --- a/dec/safe_malloc.h +++ b/dec/safe_malloc.h @@ -27,7 +27,7 @@ extern "C" { #endif /* This is the maximum memory amount that we will ever try to allocate. */ -#define BROTLI_MAX_ALLOCABLE_MEMORY (1ULL << 40) +#define BROTLI_MAX_ALLOCABLE_MEMORY (1 << 30) /* size-checking safe malloc/calloc: verify that the requested size is not too large, or return NULL. You don't need to call these for constructs like diff --git a/dec/streams.c b/dec/streams.c index 0853ad8..ac0f07e 100644 --- a/dec/streams.c +++ b/dec/streams.c @@ -72,7 +72,7 @@ BrotliOutput BrotliInitMemOutput(uint8_t* buffer, size_t length, int BrotliStdinInputFunction(void* data, uint8_t* buf, size_t count) { #ifndef _WIN32 - return read(STDIN_FILENO, buf, count); + return (int)read(STDIN_FILENO, buf, count); #else return -1; #endif @@ -87,7 +87,7 @@ BrotliInput BrotliStdinInput() { int BrotliStdoutOutputFunction(void* data, const uint8_t* buf, size_t count) { #ifndef _WIN32 - return write(STDOUT_FILENO, buf, count); + return (int)write(STDOUT_FILENO, buf, count); #else return -1; #endif