]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/indeo5.c
indeo5: check motion vectors.
[ffmpeg] / libavcodec / indeo5.c
index b1c50c2adbad05e2215efbd0c76711bb61310653..52be725721509c0da90ec9729956f45e3f415ba8 100644 (file)
@@ -76,6 +76,8 @@ typedef struct {
     int             is_scalable;
     uint32_t        lock_word;
     IVIPicConfig    pic_conf;
+
+    int gop_invalid;
 } IVI5DecContext;
 
 
@@ -336,8 +338,10 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
     ctx->frame_num = get_bits(&ctx->gb, 8);
 
     if (ctx->frame_type == FRAMETYPE_INTRA) {
+        ctx->gop_invalid = 1;
         if (decode_gop_header(ctx, avctx))
             return -1;
+        ctx->gop_invalid = 0;
     }
 
     if (ctx->frame_type != FRAMETYPE_NULL) {
@@ -446,7 +450,7 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
                           IVITile *tile, AVCodecContext *avctx)
 {
     int         x, y, mv_x, mv_y, mv_delta, offs, mb_offset,
-                mv_scale, blks_per_mb;
+                mv_scale, blks_per_mb, s;
     IVIMbInfo   *mb, *ref_mb;
     int         row_offset = band->mb_size * band->pitch;
 
@@ -454,6 +458,10 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
     ref_mb = tile->ref_mbs;
     offs   = tile->ypos * band->pitch + tile->xpos;
 
+    if (!ref_mb &&
+        ((band->qdelta_present && band->inherit_qdelta) || band->inherit_mv))
+        return AVERROR_INVALIDDATA;
+
     /* scale factor for motion vectors */
     mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
     mv_x = mv_y = 0;
@@ -542,6 +550,15 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
                 }
             }
 
+            s= band->is_halfpel;
+            if (mb->type)
+            if ( x +  (mb->mv_x   >>s) +                 (y+               (mb->mv_y   >>s))*band->pitch < 0 ||
+                 x + ((mb->mv_x+s)>>s) + band->mb_size - 1
+                   + (y+band->mb_size - 1 +((mb->mv_y+s)>>s))*band->pitch > band->bufsize - 1) {
+                av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", x*s + mb->mv_x, y*s + mb->mv_y);
+                return AVERROR_INVALIDDATA;
+            }
+
             mb++;
             if (ref_mb)
                 ref_mb++;
@@ -747,7 +764,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     ctx->frame_size = buf_size;
 
     result = decode_pic_hdr(ctx, avctx);
-    if (result) {
+    if (result || ctx->gop_invalid) {
         av_log(avctx, AV_LOG_ERROR,
                "Error while decoding picture header: %d\n", result);
         return -1;
@@ -812,7 +829,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
     ff_ivi_free_buffers(&ctx->planes[0]);
 
     if (ctx->mb_vlc.cust_tab.table)
-        free_vlc(&ctx->mb_vlc.cust_tab);
+        ff_free_vlc(&ctx->mb_vlc.cust_tab);
 
     if (ctx->frame.data[0])
         avctx->release_buffer(avctx, &ctx->frame);