mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 13:48:21 +01:00
fix underflow for very short bitstreams
+ hardened the asserts Change-Id: Ie798ef2f9d848c131f6f84a35ea28ef254822d1e
This commit is contained in:
parent
7e622984bb
commit
48b39eb17a
@ -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 {
|
||||||
|
@ -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) |
|
||||||
|
Loading…
Reference in New Issue
Block a user