]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/qpeg.c
electronicarts: Check packet sizes before reading
[ffmpeg] / libavcodec / qpeg.c
index 6092622bebeea4860402a0dcecf50f8d75c8c86d..a3a5db5c1022a5bfb45d9305452ed261eeeefb92 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct QpegContext{
     AVCodecContext *avctx;
@@ -190,6 +191,8 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
                     filled = 0;
                     dst -= stride;
                     height--;
+                    if (height < 0)
+                        break;
                 }
             }
         } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */
@@ -201,6 +204,8 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
                     filled = 0;
                     dst -= stride;
                     height--;
+                    if (height < 0)
+                        break;
                 }
             }
         } else if(code >= 0x80) { /* skip code: 0x80..0xBF */
@@ -240,14 +245,14 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
 }
 
 static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *data_size,
+                        void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     uint8_t ctable[128];
     QpegContext * const a = avctx->priv_data;
     AVFrame * const p = &a->pic;
     uint8_t* outdata;
-    int delta;
+    int delta, ret;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
     if (avpkt->size < 0x86) {
@@ -256,10 +261,9 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     bytestream2_init(&a->buffer, avpkt->data, avpkt->size);
-    p->reference = 3;
-    if (avctx->reget_buffer(avctx, p) < 0) {
+    if ((ret = ff_reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
     outdata = a->pic.data[0];
     bytestream2_skip(&a->buffer, 4);
@@ -280,8 +284,10 @@ static int decode_frame(AVCodecContext *avctx,
     }
     memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE);
 
-    *data_size = sizeof(AVFrame);
-    *(AVFrame*)data = a->pic;
+    if ((ret = av_frame_ref(data, &a->pic)) < 0)
+        return ret;
+
+    *got_frame      = 1;
 
     return avpkt->size;
 }
@@ -290,9 +296,11 @@ static av_cold int decode_init(AVCodecContext *avctx){
     QpegContext * const a = avctx->priv_data;
 
     a->avctx = avctx;
-    avctx->pix_fmt= PIX_FMT_PAL8;
+    avctx->pix_fmt= AV_PIX_FMT_PAL8;
     a->refdata = av_malloc(avctx->width * avctx->height);
 
+    avcodec_get_frame_defaults(&a->pic);
+
     return 0;
 }
 
@@ -300,8 +308,7 @@ static av_cold int decode_end(AVCodecContext *avctx){
     QpegContext * const a = avctx->priv_data;
     AVFrame * const p = &a->pic;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
+    av_frame_unref(p);
 
     av_free(a->refdata);
     return 0;