mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
fix invalid-write bug for alpha-decoding
On the non-fast path (use_8b_decode_=0) for decoding the alpha-mask, we could end up requesting ApplyInverseTransform() with more rows to process than NUM_ARGB_CACHE_ROWS. This could only happen on the very last bottom rows of the image. * ProcessRows() doesn't need to be fixed, since we never request more than NUM_ARGB_CACHE_ROWS rows. Added an assert for that. * the use_8b_decode_=1 case doesn't use argb_cache_, but rather does the palette-decoding call directly. So, no problem here too. Only the generic (and rather rare) case of calling ExtractAlphaRows() was affected. Change-Id: I58e28d590dcc08c24d237429b79614abcef1db7c
This commit is contained in:
parent
f66512db94
commit
9a583c66f9
@ -721,6 +721,9 @@ static void ProcessRows(VP8LDecoder* const dec, int row) {
|
||||
const int num_rows = row - dec->last_row_;
|
||||
|
||||
assert(row <= dec->io_->crop_bottom);
|
||||
// We can't process more than NUM_ARGB_CACHE_ROWS at a time (that's the size
|
||||
// of argb_cache_), but we currently don't need more than that.
|
||||
assert(num_rows <= NUM_ARGB_CACHE_ROWS);
|
||||
if (num_rows > 0) { // Emit output.
|
||||
VP8Io* const io = dec->io_;
|
||||
uint8_t* rows_data = (uint8_t*)dec->argb_cache_;
|
||||
@ -1464,23 +1467,31 @@ static int AllocateInternalBuffers8b(VP8LDecoder* const dec) {
|
||||
|
||||
// Special row-processing that only stores the alpha data.
|
||||
static void ExtractAlphaRows(VP8LDecoder* const dec, int last_row) {
|
||||
const int num_rows = last_row - dec->last_row_;
|
||||
const uint32_t* const in = dec->pixels_ + dec->width_ * dec->last_row_;
|
||||
int cur_row = dec->last_row_;
|
||||
int num_rows = last_row - cur_row;
|
||||
const uint32_t* in = dec->pixels_ + dec->width_ * cur_row;
|
||||
|
||||
assert(last_row <= dec->io_->crop_bottom);
|
||||
if (num_rows > 0) {
|
||||
while (num_rows > 0) {
|
||||
const int num_rows_to_process =
|
||||
(num_rows > NUM_ARGB_CACHE_ROWS) ? NUM_ARGB_CACHE_ROWS : num_rows;
|
||||
// Extract alpha (which is stored in the green plane).
|
||||
ALPHDecoder* const alph_dec = (ALPHDecoder*)dec->io_->opaque;
|
||||
uint8_t* const output = alph_dec->output_;
|
||||
const int width = dec->io_->width; // the final width (!= dec->width_)
|
||||
const int cache_pixs = width * num_rows;
|
||||
uint8_t* dst = output + width * dec->last_row_;
|
||||
const int cache_pixs = width * num_rows_to_process;
|
||||
uint8_t* const dst = output + width * cur_row;
|
||||
const uint32_t* const src = dec->argb_cache_;
|
||||
int i;
|
||||
ApplyInverseTransforms(dec, num_rows, in);
|
||||
ApplyInverseTransforms(dec, num_rows_to_process, in);
|
||||
for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff;
|
||||
AlphaApplyFilter(alph_dec, dec->last_row_, last_row, dst, width);
|
||||
AlphaApplyFilter(alph_dec,
|
||||
cur_row, cur_row + num_rows_to_process, dst, width);
|
||||
num_rows -= num_rows_to_process;
|
||||
in += num_rows_to_process * dec->width_;
|
||||
cur_row += num_rows_to_process;
|
||||
}
|
||||
assert(cur_row == last_row);
|
||||
dec->last_row_ = dec->last_out_row_ = last_row;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user