aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Barbato <lu_zero@gentoo.org>2013-07-03 14:55:50 +0200
committerLuca Barbato <lu_zero@gentoo.org>2013-09-29 21:39:02 +0200
commitefe710f8a009c99a5c4e4dff160c870cb7d95e76 (patch)
tree3eedec58bbe0f91c04fd98ed138826d9f4acfed4
parentaedde1a48de4bebdd26d27ca997b2cecc0016a45 (diff)
downloadffmpeg-efe710f8a009c99a5c4e4dff160c870cb7d95e76.tar.gz
indeo: reject negative array indexes
Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 6a10142faa1cca8ba2bfe51b970754f62d60f320) Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
-rw-r--r--libavcodec/ivi_common.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index a94285ab36..4aab7abfd7 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -42,6 +42,20 @@ VLC ff_ivi_blk_vlc_tabs[8];
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.
@@ -397,7 +411,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];
@@ -409,7 +423,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 */
@@ -425,9 +439,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;
}
@@ -516,10 +529,12 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
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;
@@ -544,7 +559,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;
@@ -622,9 +637,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 {