icecat: add release icecat-140.10.1-1gnu1 for ecne

This commit is contained in:
Ark74 2026-05-04 16:58:41 -06:00
parent a5f93cb214
commit ff85d7c623
1256 changed files with 63469 additions and 24141 deletions

View file

@ -6,9 +6,6 @@
#include <brotli/decode.h>
#include <stdlib.h> /* free, malloc */
#include <string.h> /* memcpy, memset */
#include "../common/constants.h"
#include "../common/context.h"
#include "../common/dictionary.h"
@ -20,6 +17,7 @@
#include "huffman.h"
#include "prefix.h"
#include "state.h"
#include "static_init.h"
#if defined(BROTLI_TARGET_NEON)
#include <arm_neon.h>
@ -46,16 +44,19 @@ extern "C" {
255 prefix + 32 base + 255 suffix */
static const brotli_reg_t kRingBufferWriteAheadSlack = 542;
static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
static const BROTLI_MODEL("small")
uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
};
/* Static prefix code for the complex code length code lengths. */
static const uint8_t kCodeLengthPrefixLength[16] = {
static const BROTLI_MODEL("small")
uint8_t kCodeLengthPrefixLength[16] = {
2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4,
};
static const uint8_t kCodeLengthPrefixValue[16] = {
static const BROTLI_MODEL("small")
uint8_t kCodeLengthPrefixValue[16] = {
0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5,
};
@ -78,6 +79,10 @@ BROTLI_BOOL BrotliDecoderSetParameter(
BrotliDecoderState* BrotliDecoderCreateInstance(
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
BrotliDecoderState* state = 0;
if (!BrotliDecoderEnsureStaticInit()) {
BROTLI_DUMP();
return 0;
}
if (!alloc_func && !free_func) {
state = (BrotliDecoderState*)malloc(sizeof(BrotliDecoderState));
} else if (alloc_func && free_func) {
@ -217,7 +222,7 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_LONG;
return BROTLI_DECODER_NEEDS_MORE_INPUT;
}
*value = (1U << *value) + bits;
*value = ((brotli_reg_t)1U << *value) + bits;
s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
return BROTLI_DECODER_SUCCESS;
@ -466,6 +471,53 @@ static BROTLI_INLINE brotli_reg_t ReadPreloadedSymbol(const HuffmanCode* table,
return result;
}
/* Reads up to limit symbols from br and copies them into ringbuffer,
starting from pos. Caller must ensure that there is enough space
for the write. Returns the amount of symbols actually copied. */
static BROTLI_INLINE int BrotliCopyPreloadedSymbolsToU8(const HuffmanCode* table,
BrotliBitReader* br,
brotli_reg_t* bits,
brotli_reg_t* value,
uint8_t* ringbuffer,
int pos,
const int limit) {
/* Calculate range where CheckInputAmount is always true.
Start with the number of bytes we can read. */
int64_t new_lim = br->guard_in - br->next_in;
/* Convert to bits, since symbols use variable number of bits. */
new_lim *= 8;
/* At most 15 bits per symbol, so this is safe. */
new_lim /= 15;
const int kMaximalOverread = 4;
int pos_limit = limit;
int copies = 0;
if ((new_lim - kMaximalOverread) <= limit) {
// Safe cast, since new_lim is already < num_steps
pos_limit = (int)(new_lim - kMaximalOverread);
}
if (pos_limit < 0) {
pos_limit = 0;
}
copies = pos_limit;
pos_limit += pos;
/* Fast path, caller made sure it is safe to write,
we verified that is is safe to read. */
for (; pos < pos_limit; pos++) {
BROTLI_DCHECK(BrotliCheckInputAmount(br));
ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(table, br, bits, value);
BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos);
}
/* Do the remainder, caller made sure it is safe to write,
we need to bverify that it is safe to read. */
while (BrotliCheckInputAmount(br) && copies < limit) {
ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(table, br, bits, value);
BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos);
pos++;
copies++;
}
return copies;
}
static BROTLI_INLINE brotli_reg_t Log2Floor(brotli_reg_t x) {
brotli_reg_t result = 0;
while (x) {
@ -1089,7 +1141,7 @@ static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
h->context_index = context_index;
return BROTLI_DECODER_NEEDS_MORE_INPUT;
}
reps += 1U << code;
reps += (brotli_reg_t)1U << code;
BROTLI_LOG_UINT(reps);
if (context_index + reps > context_map_size) {
return
@ -1124,7 +1176,7 @@ static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
/* 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[
@ -1135,7 +1187,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
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. */
@ -1145,11 +1197,13 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
} 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;
}
}
@ -1165,7 +1219,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
}
ringbuffer[0] = ringbuffer[1];
ringbuffer[1] = block_type;
return BROTLI_TRUE;
return BROTLI_DECODER_SUCCESS;
}
static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
@ -1202,59 +1256,65 @@ static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
/* 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(
@ -1363,6 +1423,7 @@ static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer(
static BrotliDecoderErrorCode BROTLI_NOINLINE
SkipMetadataBlock(BrotliDecoderState* s) {
BrotliBitReader* br = &s->br;
int nbytes;
if (s->meta_block_remaining_len == 0) {
return BROTLI_DECODER_SUCCESS;
@ -1373,7 +1434,7 @@ SkipMetadataBlock(BrotliDecoderState* s) {
/* Drain accumulator. */
if (BrotliGetAvailableBits(br) >= 8) {
uint8_t buffer[8];
int nbytes = (int)(BrotliGetAvailableBits(br)) >> 3;
nbytes = (int)(BrotliGetAvailableBits(br)) >> 3;
BROTLI_DCHECK(nbytes <= 8);
if (nbytes > s->meta_block_remaining_len) {
nbytes = s->meta_block_remaining_len;
@ -1390,7 +1451,7 @@ SkipMetadataBlock(BrotliDecoderState* s) {
}
/* Direct access to metadata is possible. */
int nbytes = (int)BrotliGetRemainingBytes(br);
nbytes = (int)BrotliGetRemainingBytes(br);
if (nbytes > s->meta_block_remaining_len) {
nbytes = s->meta_block_remaining_len;
}
@ -1465,6 +1526,8 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
static BROTLI_BOOL AttachCompoundDictionary(
BrotliDecoderState* state, const uint8_t* data, size_t size) {
BrotliDecoderCompoundDictionary* addon = state->compound_dictionary;
int new_size = (int)size;
if (new_size < 0 || (size_t)new_size != size) return BROTLI_FALSE;
if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE;
if (!addon) {
addon = (BrotliDecoderCompoundDictionary*)BROTLI_DECODER_ALLOC(
@ -1479,14 +1542,17 @@ static BROTLI_BOOL AttachCompoundDictionary(
state->compound_dictionary = addon;
}
if (addon->num_chunks == 15) return BROTLI_FALSE;
if (!BROTLI_SAFE_ADD(int, addon->total_size, new_size, &new_size)) {
return BROTLI_FALSE;
}
addon->chunks[addon->num_chunks] = data;
addon->num_chunks++;
addon->total_size += (int)size;
addon->chunk_offsets[addon->num_chunks] = addon->total_size;
addon->total_size = new_size;
addon->chunk_offsets[addon->num_chunks] = new_size;
return BROTLI_TRUE;
}
static void EnsureCoumpoundDictionaryInitialized(BrotliDecoderState* state) {
static void EnsureCompoundDictionaryInitialized(BrotliDecoderState* state) {
BrotliDecoderCompoundDictionary* addon = state->compound_dictionary;
/* 256 = (1 << 8) slots in block map. */
int block_bits = 8;
@ -1507,7 +1573,7 @@ static BROTLI_BOOL InitializeCompoundDictionaryCopy(BrotliDecoderState* s,
int address, int length) {
BrotliDecoderCompoundDictionary* addon = s->compound_dictionary;
int index;
EnsureCoumpoundDictionaryInitialized(s);
EnsureCompoundDictionaryInitialized(s);
index = addon->block_map[address >> addon->block_bits];
while (address >= addon->chunk_offsets[index + 1]) index++;
if (addon->total_size < address + length) return BROTLI_FALSE;
@ -1753,7 +1819,7 @@ static void CalculateDistanceLut(BrotliDecoderState* s) {
brotli_reg_t npostfix = s->distance_postfix_bits;
brotli_reg_t ndirect = s->num_direct_distance_codes;
brotli_reg_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit;
brotli_reg_t postfix = 1u << npostfix;
brotli_reg_t postfix = (brotli_reg_t)1u << npostfix;
brotli_reg_t j;
brotli_reg_t bits = 1;
brotli_reg_t half = 0;
@ -1887,6 +1953,9 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
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) { \
@ -1899,6 +1968,22 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
} \
}
/* 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;
@ -1938,7 +2023,7 @@ CommandBegin:
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. */
@ -1959,35 +2044,72 @@ CommandInner:
brotli_reg_t bits;
brotli_reg_t value;
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
do {
if (!CheckInputAmount(safe, br)) {
s->state = BROTLI_STATE_COMMAND_INNER;
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn;
if (!safe) {
// This is a hottest part of the decode, so we copy the loop below
// and optimize it by calculating the number of steps where all checks
// evaluate to false (ringbuffer size/block size/input size).
// Since all checks are loop invariant, we just need to find
// minimal number of iterations for a simple loop, and run
// the full version for the remainder.
int num_steps = i - 1;
if (num_steps > 0 && ((brotli_reg_t)(num_steps) > s->block_length[0])) {
// Safe cast, since block_length < steps
num_steps = (int)s->block_length[0];
}
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
goto NextLiteralBlock;
if (s->ringbuffer_size >= pos &&
(s->ringbuffer_size - pos) <= num_steps) {
num_steps = s->ringbuffer_size - pos - 1;
}
if (!safe) {
s->ringbuffer[pos] =
(uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
} else {
if (num_steps < 0) {
num_steps = 0;
}
num_steps = BrotliCopyPreloadedSymbolsToU8(s->literal_htree, br, &bits,
&value, s->ringbuffer, pos,
num_steps);
pos += num_steps;
s->block_length[0] -= (brotli_reg_t)num_steps;
i -= num_steps;
do {
if (!CheckInputAmount(safe, br)) {
s->state = BROTLI_STATE_COMMAND_INNER;
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn;
}
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
goto NextLiteralBlock;
}
BrotliCopyPreloadedSymbolsToU8(s->literal_htree, br, &bits, &value,
s->ringbuffer, pos, 1);
--s->block_length[0];
BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
++pos;
if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) {
s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
--i;
goto saveStateAndReturn;
}
} while (--i != 0);
} else { /* safe */
do {
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
goto NextLiteralBlock;
}
brotli_reg_t literal;
if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn;
}
s->ringbuffer[pos] = (uint8_t)literal;
}
--s->block_length[0];
BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
++pos;
if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) {
s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
--i;
goto saveStateAndReturn;
}
} while (--i != 0);
--s->block_length[0];
BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
++pos;
if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) {
s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
--i;
goto saveStateAndReturn;
}
} while (--i != 0);
}
} else {
uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask];
uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask];
@ -2046,7 +2168,7 @@ CommandPostDecodeLiterals:
} 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));
}
@ -2240,7 +2362,7 @@ CommandPostWrapCopy:
}
NextLiteralBlock:
BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
BROTLI_SAFE_WITH_STATUS(DecodeLiteralBlockSwitch(s));
goto CommandInner;
saveStateAndReturn:
@ -2462,6 +2584,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
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);
@ -2855,16 +2979,15 @@ void BrotliDecoderSetMetadataCallbacks(
/* Escalate internal functions visibility; for testing purposes only. */
#if defined(BROTLI_TEST)
BROTLI_BOOL SafeReadSymbolForTest(
BROTLI_BOOL BrotliSafeReadSymbolForTest(
const HuffmanCode*, BrotliBitReader*, brotli_reg_t*);
BROTLI_BOOL SafeReadSymbolForTest(
BROTLI_BOOL BrotliSafeReadSymbolForTest(
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
return SafeReadSymbol(table, br, result);
}
void InverseMoveToFrontTransformForTest(
void BrotliInverseMoveToFrontTransformForTest(
uint8_t*, brotli_reg_t, BrotliDecoderState*);
void InverseMoveToFrontTransformForTest(
void BrotliInverseMoveToFrontTransformForTest(
uint8_t* v, brotli_reg_t l, BrotliDecoderState* s) {
InverseMoveToFrontTransform(v, l, s);
}