fix underflow for very short bitstreams

+ hardened the asserts

Change-Id: Ie798ef2f9d848c131f6f84a35ea28ef254822d1e
This commit is contained in:
Pascal Massimino 2012-07-09 16:00:37 -07:00
parent 7e622984bb
commit 48b39eb17a
2 changed files with 12 additions and 8 deletions

View File

@ -159,7 +159,7 @@ static int ReadSymbolUnsafe(const HuffmanTree* tree, VP8LBitReader* const br) {
static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree, static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree,
VP8LBitReader* const br) { VP8LBitReader* const br) {
const int read_safe = (br->pos_ > br->len_ - 8); const int read_safe = (br->pos_ + 8 > br->len_);
if (!read_safe) { if (!read_safe) {
return ReadSymbolUnsafe(tree, br); return ReadSymbolUnsafe(tree, br);
} else { } else {

View File

@ -22,8 +22,8 @@ extern "C" {
void VP8InitBitReader(VP8BitReader* const br, void VP8InitBitReader(VP8BitReader* const br,
const uint8_t* const start, const uint8_t* const end) { const uint8_t* const start, const uint8_t* const end) {
assert(br); assert(br != NULL);
assert(start); assert(start != NULL);
assert(start <= end); assert(start <= end);
br->range_ = MK(255 - 1); br->range_ = MK(255 - 1);
br->buf_ = start; br->buf_ = start;
@ -68,7 +68,7 @@ const bit_t kVP8NewRange[128] = {
#undef MK #undef MK
void VP8LoadFinalBytes(VP8BitReader* const br) { void VP8LoadFinalBytes(VP8BitReader* const br) {
assert(br && br->buf_); assert(br != NULL && br->buf_ != NULL);
// Only read 8bits at a time // Only read 8bits at a time
if (br->buf_ < br->buf_end_) { if (br->buf_ < br->buf_end_) {
br->value_ |= (bit_t)(*br->buf_++) << ((BITS) - 8 + br->missing_); br->value_ |= (bit_t)(*br->buf_++) << ((BITS) - 8 + br->missing_);
@ -108,8 +108,9 @@ void VP8LInitBitReader(VP8LBitReader* const br,
const uint8_t* const start, const uint8_t* const start,
size_t length) { size_t length) {
size_t i; size_t i;
assert(br); assert(br != NULL);
assert(start); assert(start != NULL);
assert(length < 0xfffffff8u); // can't happen with a RIFF chunk.
br->buf_ = start; br->buf_ = start;
br->len_ = length; br->len_ = length;
@ -126,6 +127,9 @@ void VP8LInitBitReader(VP8LBitReader* const br,
void VP8LBitReaderSetBuffer(VP8LBitReader* const br, void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
const uint8_t* const buf, size_t len) { 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->eos_ = (br->pos_ >= len);
br->buf_ = buf; br->buf_ = buf;
br->len_ = len; br->len_ = len;
@ -143,7 +147,7 @@ static void ShiftBytes(VP8LBitReader* const br) {
void VP8LFillBitWindow(VP8LBitReader* const br) { void VP8LFillBitWindow(VP8LBitReader* const br) {
if (br->bit_pos_ >= 32) { if (br->bit_pos_ >= 32) {
#if defined(__x86_64__) #if defined(__x86_64__)
if (br->pos_ < br->len_ - 8) { if (br->pos_ + 8 < br->len_) {
br->val_ >>= 32; br->val_ >>= 32;
// The expression below needs a little-endian arch to work correctly. // The expression below needs a little-endian arch to work correctly.
// This gives a large speedup for decoding speed. // 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]; val = (br->val_ >> br->bit_pos_) & kBitMask[n_bits];
br->bit_pos_ += n_bits; br->bit_pos_ += n_bits;
if (br->bit_pos_ >= 40) { if (br->bit_pos_ >= 40) {
if (br->pos_ < br->len_ - 5) { if (br->pos_ + 5 < br->len_) {
br->val_ >>= 40; br->val_ >>= 40;
br->val_ |= br->val_ |=
(((uint64_t)br->buf_[br->pos_ + 0]) << 24) | (((uint64_t)br->buf_[br->pos_ + 0]) << 24) |