diff options
author | Luca Barbato <lu_zero@gentoo.org> | 2013-07-03 14:55:50 +0200 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2013-07-04 16:06:11 +0200 |
commit | 6a10142faa1cca8ba2bfe51b970754f62d60f320 (patch) | |
tree | a0923611d360d9721e41557fb551088de2e69992 | |
parent | 6dfacd7ab126aea1392949d1aa10fdc3d3eeb911 (diff) | |
download | ffmpeg-6a10142faa1cca8ba2bfe51b970754f62d60f320.tar.gz |
indeo: reject negative array indexes
Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
-rw-r--r-- | libavcodec/ivi_common.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index d4eae97126..56e024ed40 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -44,6 +44,20 @@ static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); +static int ivi_mc(ivi_mc_func mc, int16_t *buf, const int16_t *ref_buf, + int offs, int mv_x, int mv_y, uint32_t pitch, + int mc_type) +{ + int ref_offs = offs + mv_y * pitch + mv_x; + + if (offs < 0 || ref_offs < 0 || !ref_buf) + return AVERROR_INVALIDDATA; + + mc(buf + offs, ref_buf + ref_offs, pitch, mc_type); + + return 0; +} + /** * Reverse "nbits" bits of the value "val" and return the result * in the least significant bits. @@ -444,7 +458,7 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, /* de-zigzag and dequantize */ scan_pos += run; - if (scan_pos >= num_coeffs) + if (scan_pos >= num_coeffs || scan_pos < 0) break; pos = band->scan[scan_pos]; @@ -459,7 +473,7 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, col_flags[pos & col_mask] |= !!val; } - if (scan_pos >= num_coeffs && sym != rvmap->eob_sym) + if (scan_pos < 0 || scan_pos >= num_coeffs && sym != rvmap->eob_sym) return AVERROR_INVALIDDATA; /* corrupt block data */ /* undoing DC coeff prediction for intra-blocks */ @@ -475,9 +489,8 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, /* apply motion compensation */ if (!is_intra) - mc(band->buf + offs, - band->ref_buf + offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + return ivi_mc(mc, band->buf, band->ref_buf, offs, mv_x, mv_y, + band->pitch, mc_type); return 0; } @@ -579,10 +592,12 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, if (band->dc_transform) band->dc_transform(&prev_dc, band->buf + buf_offs, band->pitch, blk_size); - } else - mc_no_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + } else { + ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf, + buf_offs, mv_x, mv_y, band->pitch, mc_type); + if (ret < 0) + return ret; + } } cbp >>= 1; @@ -607,7 +622,7 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, IVITile *tile, int32_t mv_scale) { int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type; - int offs, mb_offset, row_offset; + int offs, mb_offset, row_offset, ret; IVIMbInfo *mb, *ref_mb; const int16_t *src; int16_t *dst; @@ -685,9 +700,10 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, for (blk = 0; blk < num_blocks; blk++) { /* adjust block position in the buffer according with its number */ offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch); - mc_no_delta_func(band->buf + offs, - band->ref_buf + offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf, + offs, mv_x, mv_y, band->pitch, mc_type); + if (ret < 0) + return ret; } } } else { |