mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +01:00
fix handling of zero-sized partition #0 corner case
reported in https://code.google.com/p/webp/issues/detail?id=237 An empty partition #0 should be indicative of a bitstream error. The previous code was correct, only an assert was triggered in debug mode. But we might as well handle the case properly right away... Change-Id: I4dc31a46191fa9e65659c9a5bf5de9605e93f2f5
This commit is contained in:
parent
cbcdd5ffaf
commit
205c7f26af
@ -355,30 +355,33 @@ static VP8StatusCode DecodeVP8FrameHeader(WebPIDecoder* const idec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Partition #0
|
// Partition #0
|
||||||
static int CopyParts0Data(WebPIDecoder* const idec) {
|
static VP8StatusCode CopyParts0Data(WebPIDecoder* const idec) {
|
||||||
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
|
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
|
||||||
VP8BitReader* const br = &dec->br_;
|
VP8BitReader* const br = &dec->br_;
|
||||||
const size_t psize = br->buf_end_ - br->buf_;
|
const size_t part_size = br->buf_end_ - br->buf_;
|
||||||
MemBuffer* const mem = &idec->mem_;
|
MemBuffer* const mem = &idec->mem_;
|
||||||
assert(!idec->is_lossless_);
|
assert(!idec->is_lossless_);
|
||||||
assert(mem->part0_buf_ == NULL);
|
assert(mem->part0_buf_ == NULL);
|
||||||
assert(psize > 0);
|
// the following is a format limitation, no need for runtime check:
|
||||||
assert(psize <= mem->part0_size_); // Format limit: no need for runtime check
|
assert(part_size <= mem->part0_size_);
|
||||||
|
if (part_size == 0) { // can't have zero-size partition #0
|
||||||
|
return VP8_STATUS_BITSTREAM_ERROR;
|
||||||
|
}
|
||||||
if (mem->mode_ == MEM_MODE_APPEND) {
|
if (mem->mode_ == MEM_MODE_APPEND) {
|
||||||
// We copy and grab ownership of the partition #0 data.
|
// We copy and grab ownership of the partition #0 data.
|
||||||
uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, psize);
|
uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, part_size);
|
||||||
if (part0_buf == NULL) {
|
if (part0_buf == NULL) {
|
||||||
return 0;
|
return VP8_STATUS_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
memcpy(part0_buf, br->buf_, psize);
|
memcpy(part0_buf, br->buf_, part_size);
|
||||||
mem->part0_buf_ = part0_buf;
|
mem->part0_buf_ = part0_buf;
|
||||||
br->buf_ = part0_buf;
|
br->buf_ = part0_buf;
|
||||||
br->buf_end_ = part0_buf + psize;
|
br->buf_end_ = part0_buf + part_size;
|
||||||
} else {
|
} else {
|
||||||
// Else: just keep pointers to the partition #0's data in dec_->br_.
|
// Else: just keep pointers to the partition #0's data in dec_->br_.
|
||||||
}
|
}
|
||||||
mem->start_ += psize;
|
mem->start_ += part_size;
|
||||||
return 1;
|
return VP8_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
|
static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
|
||||||
@ -412,8 +415,10 @@ static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
|
|||||||
dec->mt_method_ = VP8GetThreadMethod(params->options, NULL,
|
dec->mt_method_ = VP8GetThreadMethod(params->options, NULL,
|
||||||
io->width, io->height);
|
io->width, io->height);
|
||||||
VP8InitDithering(params->options, dec);
|
VP8InitDithering(params->options, dec);
|
||||||
if (!CopyParts0Data(idec)) {
|
|
||||||
return IDecError(idec, VP8_STATUS_OUT_OF_MEMORY);
|
dec->status_ = CopyParts0Data(idec);
|
||||||
|
if (dec->status_ != VP8_STATUS_OK) {
|
||||||
|
return IDecError(idec, dec->status_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish setting up the decoding parameters. Will call io->setup().
|
// Finish setting up the decoding parameters. Will call io->setup().
|
||||||
|
Loading…
Reference in New Issue
Block a user