]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dsicinvideo.c
doc/APIchanges: add hashes and version numbers for recent entries
[ffmpeg] / libavcodec / dsicinvideo.c
index f95cbc74a07433aef1ab3eea1260e23e38fafca0..73eea9aeb7ee86db6b266c6a1e7baf9cfedd3990 100644 (file)
@@ -58,7 +58,6 @@ static av_cold int allocate_buffers(CinVideoContext *cin)
         cin->bitmap_table[i] = av_mallocz(cin->bitmap_size);
         if (!cin->bitmap_table[i]) {
             av_log(cin->avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n");
-            destroy_buffers(cin);
             return AVERROR(ENOMEM);
         }
     }
@@ -158,6 +157,9 @@ static int cin_decode_lzss(const unsigned char *src, int src_size,
         }
     }
 
+    if (dst_end - dst > dst_size - dst_size/10)
+        return AVERROR_INVALIDDATA;
+
     return 0;
 }
 
@@ -184,6 +186,10 @@ static int cin_decode_rle(const unsigned char *src, int src_size,
         }
         dst += len;
     }
+
+    if (dst_end - dst > dst_size - dst_size/10)
+        return AVERROR_INVALIDDATA;
+
     return 0;
 }
 
@@ -226,33 +232,44 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
      * surface.width = surface.pitch */
     switch (bitmap_frame_type) {
     case 9:
-        cin_decode_rle(buf, bitmap_frame_size,
+        res =  cin_decode_rle(buf, bitmap_frame_size,
                        cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+        if (res < 0)
+            return res;
         break;
     case 34:
-        cin_decode_rle(buf, bitmap_frame_size,
+        res =  cin_decode_rle(buf, bitmap_frame_size,
                        cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+        if (res < 0)
+            return res;
         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
                              cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         break;
     case 35:
         bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
                            cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
-        cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
+        res =  cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
                        cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+        if (res < 0)
+            return res;
         break;
     case 36:
         bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
                                                cin->bitmap_table[CIN_INT_BMP],
                                                cin->bitmap_size);
-        cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
+        res = cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
                        cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+        if (res < 0)
+            return res;
         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
                              cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
         break;
     case 37:
-        cin_decode_huffman(buf, bitmap_frame_size,
+        res = cin_decode_huffman(buf, bitmap_frame_size,
                            cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+
+        if (cin->bitmap_size - avctx->discard_damaged_percentage*cin->bitmap_size/100 > res)
+            return AVERROR_INVALIDDATA;
         break;
     case 38:
         res = cin_decode_lzss(buf, bitmap_frame_size,
@@ -272,7 +289,7 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
         break;
     }
 
-    if ((res = ff_reget_buffer(avctx, cin->frame)) < 0)
+    if ((res = ff_reget_buffer(avctx, cin->frame, 0)) < 0)
         return res;
 
     memcpy(cin->frame->data[1], cin->palette, sizeof(cin->palette));
@@ -304,7 +321,7 @@ static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodec ff_dsicinvideo_decoder = {
+const AVCodec ff_dsicinvideo_decoder = {
     .name           = "dsicinvideo",
     .long_name      = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -313,5 +330,6 @@ AVCodec ff_dsicinvideo_decoder = {
     .init           = cinvideo_decode_init,
     .close          = cinvideo_decode_end,
     .decode         = cinvideo_decode_frame,
+    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .capabilities   = AV_CODEC_CAP_DR1,
 };