Roll Brotli to the latest version This updates the brotli code to the latest. The main fix is for a hang when decoding a specific sequence. Bug: 486378396 Change-Id: I563d78bfbfc94f230c62327441ccc1524ddccd5c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7683128 Reviewed-by: Kenichi Ishibashi <bashi@chromium.org> Commit-Queue: Patrick Meenan <pmeenan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1603247} NOKEYCHECK=True GitOrigin-RevId: 224140d410af003ca0266a3328accaabd24329f9
diff --git a/README.chromium b/README.chromium index 8c40eb8..bee4db5 100644 --- a/README.chromium +++ b/README.chromium
@@ -1,7 +1,7 @@ Name: Brotli URL: https://github.com/google/brotli -Version: 1.2.0 -Revision: 028fb5a23661f123017c060daa546b55cf4bde29 +Version: cfa184a997ac19454d5a3ae97f6d600aac2445a6 +Revision: cfa184a997ac19454d5a3ae97f6d600aac2445a6 Update Mechanism: Manual License: MIT License File: LICENSE
diff --git a/common/platform.h b/common/platform.h index b59f9b8..e1254d5 100644 --- a/common/platform.h +++ b/common/platform.h
@@ -213,6 +213,10 @@ #define BROTLI_TARGET_MIPS64 #endif +#if defined(__ia64__) || defined(_M_IA64) +#define BROTLI_TARGET_IA64 +#endif + #if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \ defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) || \ defined(BROTLI_TARGET_LOONGARCH64) || defined(BROTLI_TARGET_MIPS64) @@ -665,13 +669,14 @@ #undef BROTLI_TEST #endif -#if BROTLI_GNUC_HAS_ATTRIBUTE(model, 3, 0, 3) +#if !defined(BROTLI_MODEL) && BROTLI_GNUC_HAS_ATTRIBUTE(model, 3, 0, 3) && \ + !defined(BROTLI_TARGET_IA64) && !defined(BROTLI_TARGET_LOONGARCH64) #define BROTLI_MODEL(M) __attribute__((model(M))) #else #define BROTLI_MODEL(M) /* M */ #endif -#if BROTLI_GNUC_HAS_ATTRIBUTE(cold, 4, 3, 0) +#if !defined(BROTLI_COLD) && BROTLI_GNUC_HAS_ATTRIBUTE(cold, 4, 3, 0) #define BROTLI_COLD __attribute__((cold)) #else #define BROTLI_COLD /* cold */
diff --git a/dec/bit_reader.c b/dec/bit_reader.c index fae034f..a01047c 100644 --- a/dec/bit_reader.c +++ b/dec/bit_reader.c
@@ -26,12 +26,12 @@ 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF }; -void BrotliInitBitReader(BrotliBitReader* const br) { +void BrotliInitBitReader(BrotliBitReader* br) { br->val_ = 0; br->bit_pos_ = 0; } -BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) { +BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* br) { size_t aligned_read_mask = (sizeof(br->val_) >> 1) - 1; /* Fixing alignment after unaligned BrotliFillWindow would result accumulator overflow. If unalignment is caused by BrotliSafeReadBits, then there is @@ -55,7 +55,7 @@ return BROTLI_TRUE; } -BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br, +BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* br, brotli_reg_t n_bits, brotli_reg_t* val) { brotli_reg_t low_val; brotli_reg_t high_val;
diff --git a/dec/decode.c b/dec/decode.c index e87e7f5..19c7e02 100644 --- a/dec/decode.c +++ b/dec/decode.c
@@ -1176,7 +1176,7 @@ /* Decodes a command or literal and updates block type ring-buffer. Reads 3..54 bits. */ -static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength( +static BROTLI_INLINE BrotliDecoderErrorCode DecodeBlockTypeAndLength( int safe, BrotliDecoderState* s, int tree_type) { brotli_reg_t max_block_type = s->num_block_types[tree_type]; const HuffmanCode* type_tree = &s->block_type_trees[ @@ -1187,7 +1187,7 @@ brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2]; brotli_reg_t block_type; if (max_block_type <= 1) { - return BROTLI_FALSE; + return BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH; } /* Read 0..15 + 3..39 bits. */ @@ -1197,11 +1197,13 @@ } else { BrotliBitReaderState memento; BrotliBitReaderSaveState(br, &memento); - if (!SafeReadSymbol(type_tree, br, &block_type)) return BROTLI_FALSE; + if (!SafeReadSymbol(type_tree, br, &block_type)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } if (!SafeReadBlockLength(s, &s->block_length[tree_type], len_tree, br)) { s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; BrotliBitReaderRestoreState(br, &memento); - return BROTLI_FALSE; + return BROTLI_DECODER_NEEDS_MORE_INPUT; } } @@ -1217,7 +1219,7 @@ } ringbuffer[0] = ringbuffer[1]; ringbuffer[1] = block_type; - return BROTLI_TRUE; + return BROTLI_DECODER_SUCCESS; } static BROTLI_INLINE void DetectTrivialLiteralBlockTypes( @@ -1254,59 +1256,65 @@ /* Decodes the block type and updates the state for literal context. Reads 3..54 bits. */ -static BROTLI_INLINE BROTLI_BOOL DecodeLiteralBlockSwitchInternal( +static BROTLI_INLINE BrotliDecoderErrorCode DecodeLiteralBlockSwitchInternal( int safe, BrotliDecoderState* s) { - if (!DecodeBlockTypeAndLength(safe, s, 0)) { - return BROTLI_FALSE; + BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 0); + if (result != BROTLI_DECODER_SUCCESS) { + return result; } PrepareLiteralDecoding(s); - return BROTLI_TRUE; + return BROTLI_DECODER_SUCCESS; } -static void BROTLI_NOINLINE DecodeLiteralBlockSwitch(BrotliDecoderState* s) { - DecodeLiteralBlockSwitchInternal(0, s); +static BROTLI_NOINLINE BrotliDecoderErrorCode +DecodeLiteralBlockSwitch(BrotliDecoderState* s) { + return DecodeLiteralBlockSwitchInternal(0, s); } -static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch( +static BROTLI_NOINLINE BrotliDecoderErrorCode SafeDecodeLiteralBlockSwitch( BrotliDecoderState* s) { return DecodeLiteralBlockSwitchInternal(1, s); } /* Block switch for insert/copy length. Reads 3..54 bits. */ -static BROTLI_INLINE BROTLI_BOOL DecodeCommandBlockSwitchInternal( +static BROTLI_INLINE BrotliDecoderErrorCode DecodeCommandBlockSwitchInternal( int safe, BrotliDecoderState* s) { - if (!DecodeBlockTypeAndLength(safe, s, 1)) { - return BROTLI_FALSE; + BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 1); + if (result != BROTLI_DECODER_SUCCESS) { + return result; } s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]]; - return BROTLI_TRUE; + return BROTLI_DECODER_SUCCESS; } -static void BROTLI_NOINLINE DecodeCommandBlockSwitch(BrotliDecoderState* s) { - DecodeCommandBlockSwitchInternal(0, s); +static BROTLI_NOINLINE BrotliDecoderErrorCode +DecodeCommandBlockSwitch(BrotliDecoderState* s) { + return DecodeCommandBlockSwitchInternal(0, s); } -static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeCommandBlockSwitch( - BrotliDecoderState* s) { +static BROTLI_NOINLINE BrotliDecoderErrorCode +SafeDecodeCommandBlockSwitch(BrotliDecoderState* s) { return DecodeCommandBlockSwitchInternal(1, s); } /* Block switch for distance codes. Reads 3..54 bits. */ -static BROTLI_INLINE BROTLI_BOOL DecodeDistanceBlockSwitchInternal( +static BROTLI_INLINE BrotliDecoderErrorCode DecodeDistanceBlockSwitchInternal( int safe, BrotliDecoderState* s) { - if (!DecodeBlockTypeAndLength(safe, s, 2)) { - return BROTLI_FALSE; + BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 2); + if (result != BROTLI_DECODER_SUCCESS) { + return result; } s->dist_context_map_slice = s->dist_context_map + (s->block_type_rb[5] << BROTLI_DISTANCE_CONTEXT_BITS); s->dist_htree_index = s->dist_context_map_slice[s->distance_context]; - return BROTLI_TRUE; + return BROTLI_DECODER_SUCCESS; } -static void BROTLI_NOINLINE DecodeDistanceBlockSwitch(BrotliDecoderState* s) { - DecodeDistanceBlockSwitchInternal(0, s); +static BROTLI_NOINLINE BrotliDecoderErrorCode +DecodeDistanceBlockSwitch(BrotliDecoderState* s) { + return DecodeDistanceBlockSwitchInternal(0, s); } static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch( @@ -1940,6 +1948,9 @@ return BrotliCheckInputAmount(br); } +/* NB: METHOD should return BROTLI_FALSE only in case there is not enough input; + in case of "unsafe" execution, when input is guaranteed to be sufficient, + result is ignored. */ #define BROTLI_SAFE(METHOD) \ { \ if (safe) { \ @@ -1952,6 +1963,22 @@ } \ } +/* NB: METHOD should return BROTLI_DECODER_SUCCESS, BROTLI_DECODER_ERROR_*, or + BROTLI_DECODER_NEEDS_MORE_INPUT; the later two break the processing. */ +#define BROTLI_SAFE_WITH_STATUS(METHOD) \ + { \ + BrotliDecoderErrorCode status; \ + if (safe) { \ + status = Safe##METHOD; \ + } else { \ + status = METHOD; \ + } \ + if (status != BROTLI_DECODER_SUCCESS) { \ + result = status; \ + goto saveStateAndReturn; \ + } \ + } + static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal( int safe, BrotliDecoderState* s) { int pos = s->pos; @@ -1991,7 +2018,7 @@ goto saveStateAndReturn; } if (BROTLI_PREDICT_FALSE(s->block_length[1] == 0)) { - BROTLI_SAFE(DecodeCommandBlockSwitch(s)); + BROTLI_SAFE_WITH_STATUS(DecodeCommandBlockSwitch(s)); goto CommandBegin; } /* Read the insert/copy length in the command. */ @@ -2136,7 +2163,7 @@ } else { /* Read distance code in the command, unless it was implicitly zero. */ if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) { - BROTLI_SAFE(DecodeDistanceBlockSwitch(s)); + BROTLI_SAFE_WITH_STATUS(DecodeDistanceBlockSwitch(s)); } BROTLI_SAFE(ReadDistance(s, br)); } @@ -2330,7 +2357,7 @@ } NextLiteralBlock: - BROTLI_SAFE(DecodeLiteralBlockSwitch(s)); + BROTLI_SAFE_WITH_STATUS(DecodeLiteralBlockSwitch(s)); goto CommandInner; saveStateAndReturn: @@ -2552,6 +2579,8 @@ if (result != BROTLI_DECODER_SUCCESS) { break; } + BROTLI_DCHECK(s->meta_block_remaining_len <= + (int)BROTLI_BLOCK_SIZE_CAP); BROTLI_LOG_UINT(s->is_last_metablock); BROTLI_LOG_UINT(s->meta_block_remaining_len); BROTLI_LOG_UINT(s->is_metadata);
diff --git a/enc/backward_references.c b/enc/backward_references.c index 5d1c0ed..b48dd85 100644 --- a/enc/backward_references.c +++ b/enc/backward_references.c
@@ -131,6 +131,14 @@ #define PREFIX() D #define ENABLE_COMPOUND_DICTIONARY 1 +#define HASHER() H3 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#define HASHER() H4 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER #define HASHER() H5 /* NOLINTNEXTLINE(build/include) */ #include "backward_references_inc.h" @@ -192,6 +200,8 @@ literal_context_lut, params, hasher, dist_cache, \ last_insert_len, commands, num_commands, num_literals); \ return; + CASE_(3) + CASE_(4) CASE_(5) CASE_(6) #if defined(BROTLI_MAX_SIMD_QUALITY)
diff --git a/enc/backward_references_hq.c b/enc/backward_references_hq.c index ab8b121..07e82d1 100644 --- a/enc/backward_references_hq.c +++ b/enc/backward_references_hq.c
@@ -433,7 +433,7 @@ const CompoundDictionary* addon = ¶ms->dictionary.compound; size_t gap = addon->total_size; - BROTLI_DCHECK(cur_ix_masked + max_len <= ringbuffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_len <= ringbuffer_mask + 1); EvaluateNode(block_start + stream_offset, pos, max_backward_limit, gap, starting_dist_cache, model, queue, nodes);
diff --git a/enc/encode.c b/enc/encode.c index ba21aa2..9e72744 100644 --- a/enc/encode.c +++ b/enc/encode.c
@@ -245,7 +245,8 @@ static double EstimateEntropy(const uint32_t* population, size_t size) { size_t total = 0; double result = 0; - for (size_t i = 0; i < size; ++i) { + size_t i; + for (i = 0; i < size; ++i) { uint32_t p = population[i]; total += p; result += (double)p * FastLog2(p);
diff --git a/enc/hash.h b/enc/hash.h index d86fa18..eb9e455 100644 --- a/enc/hash.h +++ b/enc/hash.h
@@ -545,7 +545,7 @@ source = (const uint8_t*)BROTLI_UNALIGNED_LOAD_PTR((const uint8_t**)tail); } - BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask + 1); for (i = 0; i < 4; ++i) { const size_t distance = (size_t)distance_cache[i]; @@ -656,7 +656,7 @@ source = (const uint8_t*)BROTLI_UNALIGNED_LOAD_PTR((const uint8_t**)tail); } - BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask + 1); while (item == 0) { size_t offset;
diff --git a/enc/hash_forgetful_chain_inc.h b/enc/hash_forgetful_chain_inc.h index c44276f..b653698 100644 --- a/enc/hash_forgetful_chain_inc.h +++ b/enc/hash_forgetful_chain_inc.h
@@ -213,7 +213,7 @@ out->len = 0; out->len_code_delta = 0; - BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask + 1); /* Try last distance first. */ for (i = 0; i < NUM_LAST_DISTANCES_TO_CHECK; ++i) {
diff --git a/enc/hash_longest_match64_inc.h b/enc/hash_longest_match64_inc.h index bdbb30a..3131451 100644 --- a/enc/hash_longest_match64_inc.h +++ b/enc/hash_longest_match64_inc.h
@@ -178,7 +178,7 @@ out->len = 0; out->len_code_delta = 0; - BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask + 1); /* Try last distance first. */ for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) {
diff --git a/enc/hash_longest_match64_simd_inc.h b/enc/hash_longest_match64_simd_inc.h index 12bd8cf..17dc67d 100644 --- a/enc/hash_longest_match64_simd_inc.h +++ b/enc/hash_longest_match64_simd_inc.h
@@ -195,7 +195,7 @@ out->len = 0; out->len_code_delta = 0; - BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask + 1); /* Try last distance first. */ for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) {
diff --git a/enc/hash_longest_match_inc.h b/enc/hash_longest_match_inc.h index 58e88b3..674dced 100644 --- a/enc/hash_longest_match_inc.h +++ b/enc/hash_longest_match_inc.h
@@ -178,7 +178,7 @@ out->len = 0; out->len_code_delta = 0; - BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask + 1); /* Try last distance first. */ for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) {
diff --git a/enc/hash_longest_match_quickly_inc.h b/enc/hash_longest_match_quickly_inc.h index 57ed586..12fdb44 100644 --- a/enc/hash_longest_match_quickly_inc.h +++ b/enc/hash_longest_match_quickly_inc.h
@@ -165,10 +165,10 @@ size_t cached_backward = (size_t)distance_cache[0]; size_t prev_ix = cur_ix - cached_backward; - BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask + 1); out->len_code_delta = 0; - if (prev_ix < cur_ix) { + if (prev_ix < cur_ix && cached_backward <= max_backward) { prev_ix &= (uint32_t)ring_buffer_mask; if (compare_char == data[prev_ix + best_len]) { const size_t len = FindMatchLengthWithLimit(
diff --git a/enc/hash_longest_match_simd_inc.h b/enc/hash_longest_match_simd_inc.h index 79b341a..075f6da 100644 --- a/enc/hash_longest_match_simd_inc.h +++ b/enc/hash_longest_match_simd_inc.h
@@ -170,7 +170,7 @@ out->len = 0; out->len_code_delta = 0; - BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask + 1); /* Try last distance first. */ for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) {
diff --git a/include/brotli/decode.h b/include/brotli/decode.h index 8d436db..10d01e3 100644 --- a/include/brotli/decode.h +++ b/include/brotli/decode.h
@@ -85,9 +85,7 @@ BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR \ BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR \ BROTLI_ERROR_CODE(_ERROR_FORMAT_, DISTANCE, -16) SEPARATOR \ - \ - /* -17 code is reserved */ \ - \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_SWITCH, -17) SEPARATOR \ BROTLI_ERROR_CODE(_ERROR_, COMPOUND_DICTIONARY, -18) SEPARATOR \ BROTLI_ERROR_CODE(_ERROR_, DICTIONARY_NOT_SET, -19) SEPARATOR \ BROTLI_ERROR_CODE(_ERROR_, INVALID_ARGUMENTS, -20) SEPARATOR \