From 48b39eb17a241cf000eb58b3c245f3ac3fbd7341 Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Mon, 9 Jul 2012 16:00:37 -0700 Subject: [PATCH] fix underflow for very short bitstreams + hardened the asserts Change-Id: Ie798ef2f9d848c131f6f84a35ea28ef254822d1e --- src/dec/vp8l.c | 2 +- src/utils/bit_reader.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/dec/vp8l.c b/src/dec/vp8l.c index 311eda42..473bb300 100644 --- a/src/dec/vp8l.c +++ b/src/dec/vp8l.c @@ -159,7 +159,7 @@ static int ReadSymbolUnsafe(const HuffmanTree* tree, VP8LBitReader* const br) { static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree, VP8LBitReader* const br) { - const int read_safe = (br->pos_ > br->len_ - 8); + const int read_safe = (br->pos_ + 8 > br->len_); if (!read_safe) { return ReadSymbolUnsafe(tree, br); } else { diff --git a/src/utils/bit_reader.c b/src/utils/bit_reader.c index 5c0eec4e..7ff0efb6 100644 --- a/src/utils/bit_reader.c +++ b/src/utils/bit_reader.c @@ -22,8 +22,8 @@ extern "C" { void VP8InitBitReader(VP8BitReader* const br, const uint8_t* const start, const uint8_t* const end) { - assert(br); - assert(start); + assert(br != NULL); + assert(start != NULL); assert(start <= end); br->range_ = MK(255 - 1); br->buf_ = start; @@ -68,7 +68,7 @@ const bit_t kVP8NewRange[128] = { #undef MK void VP8LoadFinalBytes(VP8BitReader* const br) { - assert(br && br->buf_); + assert(br != NULL && br->buf_ != NULL); // Only read 8bits at a time if (br->buf_ < br->buf_end_) { br->value_ |= (bit_t)(*br->buf_++) << ((BITS) - 8 + br->missing_); @@ -108,8 +108,9 @@ void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start, size_t length) { size_t i; - assert(br); - assert(start); + assert(br != NULL); + assert(start != NULL); + assert(length < 0xfffffff8u); // can't happen with a RIFF chunk. br->buf_ = start; br->len_ = length; @@ -126,6 +127,9 @@ void VP8LInitBitReader(VP8LBitReader* const br, void VP8LBitReaderSetBuffer(VP8LBitReader* const br, const uint8_t* const buf, size_t len) { + assert(br != NULL); + assert(buf != NULL); + assert(len < 0xfffffff8u); // can't happen with a RIFF chunk. br->eos_ = (br->pos_ >= len); br->buf_ = buf; br->len_ = len; @@ -143,7 +147,7 @@ static void ShiftBytes(VP8LBitReader* const br) { void VP8LFillBitWindow(VP8LBitReader* const br) { if (br->bit_pos_ >= 32) { #if defined(__x86_64__) - if (br->pos_ < br->len_ - 8) { + if (br->pos_ + 8 < br->len_) { br->val_ >>= 32; // The expression below needs a little-endian arch to work correctly. // This gives a large speedup for decoding speed. @@ -197,7 +201,7 @@ uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) { val = (br->val_ >> br->bit_pos_) & kBitMask[n_bits]; br->bit_pos_ += n_bits; if (br->bit_pos_ >= 40) { - if (br->pos_ < br->len_ - 5) { + if (br->pos_ + 5 < br->len_) { br->val_ >>= 40; br->val_ |= (((uint64_t)br->buf_[br->pos_ + 0]) << 24) |