diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2015-02-11 03:33:53 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-02-12 17:10:36 +0100 |
commit | 345962121d76aaf2faf841a50577221457fb8ee0 (patch) | |
tree | ff669765feb524239da41bfad72d8b1bc04bcba2 | |
parent | 0cbf53bdf51623f42938ffaddb5c3fd06295995e (diff) | |
download | ffmpeg-345962121d76aaf2faf841a50577221457fb8ee0.tar.gz |
avcodec/mjpegdec: Skip blocks which are outside the visible area
Fixes out of array accesses
Fixes: ffmpeg_mjpeg_crash.avi
Found-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 08509c8f86626815a3e9e68d600d1aacbb8df4bf)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/mjpegdec.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 17b6993aaa..bf674581d3 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1251,13 +1251,18 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, if (s->interlaced && s->bottom_field) block_offset += linesize[c] >> 1; - ptr = data[c] + block_offset; + if ( 8*(h * mb_x + x) < s->width + && 8*(v * mb_y + y) < s->height) { + ptr = data[c] + block_offset; + } else + ptr = NULL; if (!s->progressive) { - if (copy_mb) - mjpeg_copy_block(s, ptr, reference_data[c] + block_offset, - linesize[c], s->avctx->lowres); + if (copy_mb) { + if (ptr) + mjpeg_copy_block(s, ptr, reference_data[c] + block_offset, + linesize[c], s->avctx->lowres); - else { + } else { s->bdsp.clear_block(s->block); if (decode_block(s, s->block, i, s->dc_index[i], s->ac_index[i], @@ -1266,9 +1271,11 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, "error y=%d x=%d\n", mb_y, mb_x); return AVERROR_INVALIDDATA; } - s->idsp.idct_put(ptr, linesize[c], s->block); - if (s->bits & 7) - shift_output(s, ptr, linesize[c]); + if (ptr) { + s->idsp.idct_put(ptr, linesize[c], s->block); + if (s->bits & 7) + shift_output(s, ptr, linesize[c]); + } } } else { int block_idx = s->block_stride[c] * (v * mb_y + y) + |