From 19f28b7889aff7d1ed4ac9dfa9097267e805aaa0 Mon Sep 17 00:00:00 2001 From: Arman Hasanzadeh Date: Tue, 12 Aug 2025 16:35:56 -0700 Subject: [PATCH] Add fbounds-safety annotations for `VP8LBitReader`. Reasoning: Analysis of the `VP8LBitReader` struct and its initialization function `VP8LInitBitReader` confirmed that the `len` member holds the size of the buffer pointed to by `buf`. Therefore, `__counted_by(len)` was added to `buf` in the struct definition. This introduced new errors related to function parameters being treated as `__single` and the `__counted_by` side-by-side assignment rule: 1. In `VP8LInitBitReader`, the `start` parameter was indexed (`start[i]`) but was implicitly `__single`. It was annotated with `__counted_by(length)` in both the definition and prototype. 2. `br->buf = start` was moved immediately after `br->len = length`. 3. In `VP8LBitReaderSetBuffer`, the `buf` parameter was assigned to `br->buf`, which requires the parameter to also be annotated. `__counted_by(len)` was added to the `buf` parameter in the definition and `__counted_by(length)` to the `buffer` parameter in the prototype. Bug: 432511821 Change-Id: Ie2d5b7b321fb02e8c6b6d3cbd933d056b1bb82cf --- src/utils/bit_reader_utils.c | 8 +++++--- src/utils/bit_reader_utils.h | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/utils/bit_reader_utils.c b/src/utils/bit_reader_utils.c index b34a84aa..3a2f1d2e 100644 --- a/src/utils/bit_reader_utils.c +++ b/src/utils/bit_reader_utils.c @@ -130,7 +130,8 @@ static const uint32_t kBitMask[VP8L_MAX_NUM_BIT_READ + 1] = { 0x003fff, 0x007fff, 0x00ffff, 0x01ffff, 0x03ffff, 0x07ffff, 0x0fffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff}; -void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start, +void VP8LInitBitReader(VP8LBitReader* const br, + const uint8_t* const WEBP_COUNTED_BY(length) start, size_t length) { size_t i; vp8l_val_t value = 0; @@ -138,6 +139,7 @@ void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start, assert(start != NULL); assert(length < 0xfffffff8u); // can't happen with a RIFF chunk. + br->buf = start; br->len = length; br->val = 0; br->bit_pos = 0; @@ -151,10 +153,10 @@ void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start, } br->val = value; br->pos = length; - br->buf = start; } -void VP8LBitReaderSetBuffer(VP8LBitReader* const br, const uint8_t* const buf, +void VP8LBitReaderSetBuffer(VP8LBitReader* const br, + const uint8_t* const WEBP_COUNTED_BY(len) buf, size_t len) { assert(br != NULL); assert(buf != NULL); diff --git a/src/utils/bit_reader_utils.h b/src/utils/bit_reader_utils.h index f926dcf7..efb217a5 100644 --- a/src/utils/bit_reader_utils.h +++ b/src/utils/bit_reader_utils.h @@ -146,20 +146,22 @@ int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits, typedef uint64_t vp8l_val_t; // right now, this bit-reader can only use 64bit. typedef struct { - vp8l_val_t val; // pre-fetched bits - const uint8_t* buf; // input byte buffer - size_t len; // buffer length - size_t pos; // byte position in buf - int bit_pos; // current bit-reading position in val - int eos; // true if a bit was read past the end of buffer + vp8l_val_t val; // pre-fetched bits + const uint8_t* WEBP_COUNTED_BY(len) buf; // input byte buffer + size_t len; // buffer length + size_t pos; // byte position in buf + int bit_pos; // current bit-reading position in val + int eos; // true if a bit was read past the end of buffer } VP8LBitReader; -void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start, +void VP8LInitBitReader(VP8LBitReader* const br, + const uint8_t* const WEBP_COUNTED_BY(length) start, size_t length); // Sets a new data buffer. void VP8LBitReaderSetBuffer(VP8LBitReader* const br, - const uint8_t* const buffer, size_t length); + const uint8_t* const WEBP_COUNTED_BY(length) buffer, + size_t length); // Reads the specified number of bits from read buffer. // Flags an error in case end_of_stream or n_bits is more than the allowed limit