]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/qdrw.c
8svx: fix memleak in iff-fibonacci fate test.
[ffmpeg] / libavcodec / qdrw.c
index cd3146388e05bee5ee01691af5a53b2f1afd667d..54deec5c83545c0d56e93e72f97dca78b5ced4a7 100644 (file)
@@ -37,6 +37,7 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
+    const uint8_t *buf_end = avpkt->data + avpkt->size;
     int buf_size = avpkt->size;
     QdrawContext * const a = avctx->priv_data;
     AVFrame * const p= (AVFrame*)&a->pic;
@@ -59,6 +60,8 @@ static int decode_frame(AVCodecContext *avctx,
 
     outdata = a->pic.data[0];
 
+    if (buf_end - buf < 0x68 + 4)
+        return AVERROR_INVALIDDATA;
     buf += 0x68; /* jump to palette */
     colors = AV_RB32(buf);
     buf += 4;
@@ -67,6 +70,8 @@ static int decode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors);
         return -1;
     }
+    if (buf_end - buf < (colors + 1) * 8)
+        return AVERROR_INVALIDDATA;
 
     pal = (uint32_t*)p->data[1];
     for (i = 0; i <= colors; i++) {
@@ -85,10 +90,12 @@ static int decode_frame(AVCodecContext *avctx,
         buf++;
         b = *buf++;
         buf++;
-        pal[idx] = (r << 16) | (g << 8) | b;
+        pal[idx] = 0xFF << 24 | r << 16 | g << 8 | b;
     }
     p->palette_has_changed = 1;
 
+    if (buf_end - buf < 18)
+        return AVERROR_INVALIDDATA;
     buf += 18; /* skip unneeded data */
     for (i = 0; i < avctx->height; i++) {
         int size, left, code, pix;
@@ -100,6 +107,9 @@ static int decode_frame(AVCodecContext *avctx,
         out = outdata;
         size = AV_RB16(buf); /* size of packed line */
         buf += 2;
+        if (buf_end - buf < size)
+            return AVERROR_INVALIDDATA;
+
         left = size;
         next = buf + size;
         while (left > 0) {
@@ -115,6 +125,8 @@ static int decode_frame(AVCodecContext *avctx,
             } else { /* copy */
                 if ((out + code) > (outdata +  a->pic.linesize[0]))
                     break;
+                if (buf_end - buf < code + 1)
+                    return AVERROR_INVALIDDATA;
                 memcpy(out, buf, code + 1);
                 out += code + 1;
                 buf += code + 1;
@@ -152,14 +164,13 @@ static av_cold int decode_end(AVCodecContext *avctx){
 }
 
 AVCodec ff_qdraw_decoder = {
-    "qdraw",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_QDRAW,
-    sizeof(QdrawContext),
-    decode_init,
-    NULL,
-    decode_end,
-    decode_frame,
-    CODEC_CAP_DR1,
+    .name           = "qdraw",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = CODEC_ID_QDRAW,
+    .priv_data_size = sizeof(QdrawContext),
+    .init           = decode_init,
+    .close          = decode_end,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"),
 };