]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/eamad.c
mpegvideo_parser: fix buffer access beyond end
[ffmpeg] / libavcodec / eamad.c
index 280519518da93f8e77d70c774b1c37f740820084..2f9559fe8e0459797939bbd575cb512c14d78673 100644 (file)
@@ -33,6 +33,7 @@
 #include "dsputil.h"
 #include "aandcttab.h"
 #include "eaidct.h"
+#include "internal.h"
 #include "mpeg12.h"
 #include "mpeg12data.h"
 #include "libavutil/imgutils.h"
@@ -226,21 +227,21 @@ static void calc_quant_matrix(MadContext *s, int qscale)
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     const uint8_t *buf_end = buf+buf_size;
     MadContext *s     = avctx->priv_data;
-    int width, height;
+    int width, height, ret;
     int chunk_type;
     int inter;
 
-    if (buf_size < 17) {
+    if (buf_size < 26) {
         av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n");
-        *data_size = 0;
-        return -1;
+        *got_frame = 0;
+        return AVERROR_INVALIDDATA;
     }
 
     chunk_type = AV_RL32(&buf[0]);
@@ -257,9 +258,9 @@ static int decode_frame(AVCodecContext *avctx,
 
     if (avctx->width != width || avctx->height != height) {
         if((width * height)/2048*7 > buf_end-buf)
-            return -1;
-        if (av_image_check_size(width, height, 0, avctx) < 0)
-            return -1;
+            return AVERROR_INVALIDDATA;
+        if ((ret = av_image_check_size(width, height, 0, avctx)) < 0)
+            return ret;
         avcodec_set_dimensions(avctx, width, height);
         if (s->frame.data[0])
             avctx->release_buffer(avctx, &s->frame);
@@ -269,13 +270,14 @@ static int decode_frame(AVCodecContext *avctx,
 
     s->frame.reference = 3;
     if (!s->frame.data[0]) {
-        if (avctx->get_buffer(avctx, &s->frame) < 0) {
+        if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
     }
 
-    av_fast_malloc(&s->bitstream_buf, &s->bitstream_buf_size, (buf_end-buf) + FF_INPUT_BUFFER_PADDING_SIZE);
+    av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
+                          buf_end - buf);
     if (!s->bitstream_buf)
         return AVERROR(ENOMEM);
     s->dsp.bswap16_buf(s->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2);
@@ -285,9 +287,9 @@ static int decode_frame(AVCodecContext *avctx,
     for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
         for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
             if(decode_mb(s, inter) < 0)
-                return -1;
+                return AVERROR_INVALIDDATA;
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     if (chunk_type != MADe_TAG)