Add fbounds-safety annotations for pool.

Reasoning:

The `pool` parameter in the static function `SetBitDepths`
(`src/utils/huffman_encode_utils.c:140`) is indexed as an array. Since
the function is static and the exact size is not available in the
signature, `pool` was annotated as `__bidi_indexable`. This required
updating the caller, `GenerateOptimalTree` (also static), where the
corresponding argument `tree_pool` is derived from the `tree` parameter.
Consequently, both the `tree` parameter and the local variable
`tree_pool` in `GenerateOptimalTree`
(`src/utils/huffman_encode_utils.c:170`) were also annotated as
`__bidi_indexable`. Finally, the call to `GenerateOptimalTree` from the
ABI-visible function `VP8LCreateHuffmanTree`
(`src/utils/huffman_encode_utils.c:417`) required adapting the
`huff_tree` pointer. Tracing the allocation in `src/enc/vp8l_enc.c:473`
revealed that `huff_tree` is allocated with enough space for
`3 * max_num_symbols`. Therefore, `__unsafe_forge_bidi_indexable` was
used to cast `huff_tree` to `__bidi_indexable` with the calculated
bounds (`3 * num_symbols`).

Bug: 432511821
Change-Id: I53c6965c3fd708256241a225ec9223085a1ec2d4
This commit is contained in:
Arman Hasanzadeh
2025-08-18 23:31:14 -07:00
parent 3f96cbffa2
commit 10d81e1ef0

View File

@@ -138,7 +138,7 @@ static int CompareHuffmanTrees(const void* ptr1, const void* ptr2) {
} }
static void SetBitDepths(const HuffmanTree* const tree, static void SetBitDepths(const HuffmanTree* const tree,
const HuffmanTree* const pool, const HuffmanTree* WEBP_BIDI_INDEXABLE const pool,
uint8_t* WEBP_INDEXABLE const bit_depths, int level) { uint8_t* WEBP_INDEXABLE const bit_depths, int level) {
if (tree->pool_index_left >= 0) { if (tree->pool_index_left >= 0) {
SetBitDepths(&pool[tree->pool_index_left], pool, bit_depths, level + 1); SetBitDepths(&pool[tree->pool_index_left], pool, bit_depths, level + 1);
@@ -168,12 +168,13 @@ static void SetBitDepths(const HuffmanTree* const tree,
// //
// See https://en.wikipedia.org/wiki/Huffman_coding // See https://en.wikipedia.org/wiki/Huffman_coding
static void GenerateOptimalTree(const uint32_t* const histogram, static void GenerateOptimalTree(const uint32_t* const histogram,
int histogram_size, HuffmanTree* tree, int histogram_size,
HuffmanTree* WEBP_BIDI_INDEXABLE tree,
int tree_depth_limit, int tree_depth_limit,
uint8_t* WEBP_COUNTED_BY(histogram_size) uint8_t* WEBP_COUNTED_BY(histogram_size)
const bit_depths) { const bit_depths) {
uint32_t count_min; uint32_t count_min;
HuffmanTree* tree_pool; HuffmanTree* WEBP_BIDI_INDEXABLE tree_pool;
int tree_size_orig = 0; int tree_size_orig = 0;
int i; int i;
@@ -232,8 +233,7 @@ static void GenerateOptimalTree(const uint32_t* const histogram,
break; break;
} }
} }
WEBP_UNSAFE_MEMMOVE(tree + (k + 1), tree + k, memmove(tree + (k + 1), tree + k, (tree_size - k) * sizeof(*tree));
(tree_size - k) * sizeof(*tree));
tree[k].total_count = count; tree[k].total_count = count;
tree[k].value = -1; tree[k].value = -1;
@@ -415,8 +415,11 @@ void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit,
const int num_symbols = huff_code->num_symbols; const int num_symbols = huff_code->num_symbols;
WEBP_UNSAFE_MEMSET(buf_rle, 0, num_symbols * sizeof(*buf_rle)); WEBP_UNSAFE_MEMSET(buf_rle, 0, num_symbols * sizeof(*buf_rle));
OptimizeHuffmanForRle(num_symbols, buf_rle, histogram); OptimizeHuffmanForRle(num_symbols, buf_rle, histogram);
GenerateOptimalTree(histogram, num_symbols, huff_tree, tree_depth_limit, GenerateOptimalTree(
huff_code->code_lengths); histogram, num_symbols,
WEBP_UNSAFE_FORGE_BIDI_INDEXABLE(HuffmanTree*, huff_tree,
3 * num_symbols * sizeof(*huff_tree)),
tree_depth_limit, huff_code->code_lengths);
// Create the actual bit codes for the bit lengths. // Create the actual bit codes for the bit lengths.
ConvertBitDepthsToSymbols(huff_code); ConvertBitDepthsToSymbols(huff_code);
} }