avcodec/mjpegdec: Skip blocks which are outside the visible area
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 11 Feb 2015 02:33:53 +0000 (03:33 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 12 Mar 2015 17:03:50 +0000 (18:03 +0100)
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)

Conflicts:

libavcodec/mjpegdec.c
(cherry picked from commit 0bb0716d9c0699895abcef2d3954c1d6e4157cb2)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/mjpegdec.c

index e2706f2..655bc8e 100644 (file)
@@ -1029,12 +1029,17 @@ 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(ptr, reference_data[c] + block_offset,
-                                             linesize[c], s->avctx->lowres);
-                        else {
+                        if (copy_mb) {
+                            if (ptr)
+                                mjpeg_copy_block(ptr, reference_data[c] + block_offset,
+                                                linesize[c], s->avctx->lowres);
+                        } else {
                             s->dsp.clear_block(s->block);
                             if (decode_block(s, s->block, i,
                                              s->dc_index[i], s->ac_index[i],
@@ -1043,7 +1048,9 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
                                        "error y=%d x=%d\n", mb_y, mb_x);
                                 return -1;
                             }
-                            s->dsp.idct_put(ptr, linesize[c], s->block);
+                            if (ptr) {
+                                s->dsp.idct_put(ptr, linesize[c], s->block);
+                            }
                         }
                     } else {
                         int block_idx  = s->block_stride[c] * (v * mb_y + y) +