From 101e2b303fc0450f193799f5cd7b0ac50a4fd0f7 Mon Sep 17 00:00:00 2001 From: Arman Hasanzadeh Date: Mon, 18 Aug 2025 18:57:06 -0700 Subject: [PATCH] Add fbounds-safety annotations for `tokens`. Reasoning: The errors reported for `tokens` in `CodeRepeatedValues` (src/utils/huffman_encode_utils.c, lines 274, 283, 289, 294) indicated pointer arithmetic on a pointer assumed to be `__single`. Since `CodeRepeatedValues` is static and uses `tokens` as an iterator, its signature was changed to use `HuffmanTreeToken* __indexable` for both the parameter and return type. A similar static function, `CodeRepeatedZeros`, was also updated to use `__indexable` pointers. The caller, `VP8LCreateCompressedHuffmanTree`, passes a buffer `tokens` with size `max_tokens`. Its signature (in .c and .h files) was annotated to reflect this using `__counted_by(max_tokens)`. Because `__counted_by` requires the size parameter to be updated alongside the pointer if the pointer is modified, the implementation of `VP8LCreateCompressedHuffmanTree` was refactored. Instead of modifying the `tokens` parameter directly, a local iterator variable `current_token` was introduced and explicitly annotated as `__indexable` to ensure correct type propagation, especially when `WEBP_ASSUME_UNSAFE_INDEXABLE_ABI` is active. This local iterator is used for calls to `CodeRepeatedValues` and `CodeRepeatedZeros`. Bug: 432511821 Change-Id: I07fe553341a613a0ea4d5284817098c31f3aefeb --- src/utils/huffman_encode_utils.c | 25 ++++++++++++++----------- src/utils/huffman_encode_utils.h | 5 +++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/utils/huffman_encode_utils.c b/src/utils/huffman_encode_utils.c index 1b18f384..c60d9c6f 100644 --- a/src/utils/huffman_encode_utils.c +++ b/src/utils/huffman_encode_utils.c @@ -265,9 +265,9 @@ static void GenerateOptimalTree(const uint32_t* const histogram, // ----------------------------------------------------------------------------- // Coding of the Huffman tree values -static HuffmanTreeToken* CodeRepeatedValues(int repetitions, - HuffmanTreeToken* tokens, int value, - int prev_value) { +static HuffmanTreeToken* WEBP_INDEXABLE +CodeRepeatedValues(int repetitions, HuffmanTreeToken* WEBP_INDEXABLE tokens, + int value, int prev_value) { assert(value <= MAX_ALLOWED_CODE_LENGTH); if (value != prev_value) { tokens->code = value; @@ -299,8 +299,8 @@ static HuffmanTreeToken* CodeRepeatedValues(int repetitions, return tokens; } -static HuffmanTreeToken* CodeRepeatedZeros(int repetitions, - HuffmanTreeToken* tokens) { +static HuffmanTreeToken* WEBP_INDEXABLE +CodeRepeatedZeros(int repetitions, HuffmanTreeToken* WEBP_INDEXABLE tokens) { while (repetitions >= 1) { if (repetitions < 3) { int i; @@ -330,8 +330,10 @@ static HuffmanTreeToken* CodeRepeatedZeros(int repetitions, return tokens; } -int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree, - HuffmanTreeToken* tokens, int max_tokens) { +int VP8LCreateCompressedHuffmanTree( + const HuffmanTreeCode* const tree, + HuffmanTreeToken* WEBP_COUNTED_BY(max_tokens) tokens, int max_tokens) { + HuffmanTreeToken* WEBP_INDEXABLE current_token = tokens; HuffmanTreeToken* const starting_token = tokens; HuffmanTreeToken* const ending_token = tokens + max_tokens; const int depth_size = tree->num_symbols; @@ -345,16 +347,17 @@ int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree, while (k < depth_size && tree->code_lengths[k] == value) ++k; runs = k - i; if (value == 0) { - tokens = CodeRepeatedZeros(runs, tokens); + current_token = CodeRepeatedZeros(runs, current_token); } else { - tokens = CodeRepeatedValues(runs, tokens, value, prev_value); + current_token = + CodeRepeatedValues(runs, current_token, value, prev_value); prev_value = value; } i += runs; - assert(tokens <= ending_token); + assert(current_token <= ending_token); } (void)ending_token; // suppress 'unused variable' warning - return (int)(tokens - starting_token); + return (int)(current_token - starting_token); } // ----------------------------------------------------------------------------- diff --git a/src/utils/huffman_encode_utils.h b/src/utils/huffman_encode_utils.h index d80f96b1..f4a6f669 100644 --- a/src/utils/huffman_encode_utils.h +++ b/src/utils/huffman_encode_utils.h @@ -48,8 +48,9 @@ typedef struct { // Turn the Huffman tree into a token sequence. // Returns the number of tokens used. -int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree, - HuffmanTreeToken* tokens, int max_tokens); +int VP8LCreateCompressedHuffmanTree( + const HuffmanTreeCode* const tree, + HuffmanTreeToken* WEBP_COUNTED_BY(max_tokens) tokens, int max_tokens); // Create an optimized tree, and tokenize it. // 'buf_rle' and 'huff_tree' are pre-allocated and the 'tree' is the constructed