diff --git a/pik/ans_decode.cc b/pik/ans_decode.cc index a3746f0..0461e5c 100644 --- a/pik/ans_decode.cc +++ b/pik/ans_decode.cc @@ -96,6 +96,9 @@ Status ReadHistogram(int precision_bits, std::vector* counts, input->FillBitBuffer(); int rle_length = input->PeekFixedBits<8>(); input->Advance(8); + if (rle_length < 2) { + return PIK_FAILURE("Invalid RLE length in histogram"); + } same[i] = rle_length; i += rle_length - 2; continue; diff --git a/pik/entropy_coder.cc b/pik/entropy_coder.cc index 615397b..44ef62a 100644 --- a/pik/entropy_coder.cc +++ b/pik/entropy_coder.cc @@ -973,6 +973,10 @@ bool DecodeQuantField(BitReader* PIK_RESTRICT br, } else { row_quant[bx] = UnpackSigned(q) + predicted_quant; } + if (by + acs.covered_blocks_y() > ysize || + bx + acs.covered_blocks_x() > xsize) { + return PIK_FAILURE("AC strategy extends outside quant field"); + } for (size_t iy = 0; iy < acs.covered_blocks_y(); iy++) { for (size_t ix = 0; ix < acs.covered_blocks_x(); ix++) { row_quant[bx + iy * stride + ix] = row_quant[bx]; @@ -998,6 +1002,10 @@ bool DecodeQuantField(BitReader* PIK_RESTRICT br, } else { row_quant[bx] = UnpackSigned(q) + predicted_quant; } + if (by + acs.covered_blocks_y() > ysize || + bx + acs.covered_blocks_x() > xsize) { + return PIK_FAILURE("AC strategy extends outside quant field"); + } for (size_t iy = 0; iy < acs.covered_blocks_y(); iy++) { for (size_t ix = 0; ix < acs.covered_blocks_x(); ix++) { row_quant[bx + iy * stride + ix] = row_quant[bx]; diff --git a/pik/quant_weights.cc b/pik/quant_weights.cc index f7dc81e..2bb5620 100644 --- a/pik/quant_weights.cc +++ b/pik/quant_weights.cc @@ -951,6 +951,9 @@ bool DecodeDequantControlField(BitReader* PIK_RESTRICT br, for (size_t x = 0; x < dequant_cf->xsize(); ++x) { br->FillBitBuffer(); row[x] = decoder.ReadSymbol(entropy, br); + if (row[x] >= kMaxQuantControlFieldValue) { + return PIK_FAILURE("dequant_cf value out of range"); + } } } PIK_RETURN_IF_ERROR(br->JumpToByteBoundary());