mss2: prevent potential uninitialized reads
[ffmpeg.git] / libavcodec / mss2.c
index 597ebb6..bec3f45 100644 (file)
@@ -474,7 +474,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     int keyframe, has_wmv9, has_mv, is_rle, is_555, ret;
 
     Rectangle wmv9rects[MAX_WMV9_RECTANGLES], *r;
-    int used_rects = 0, i, implicit_rect, av_uninit(wmv9_mask);
+    int used_rects = 0, i, implicit_rect = 0, av_uninit(wmv9_mask);
 
     av_assert0(FF_INPUT_BUFFER_PADDING_SIZE >=
                ARITH2_PADDING + (MIN_CACHE_BITS + 7) / 8);
@@ -650,25 +650,6 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
             return AVERROR_INVALIDDATA;
 
         buf_size -= bytestream2_tell(&gB);
-    } else if (is_rle) {
-        init_get_bits(&gb, buf, buf_size * 8);
-        if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
-                             c->rgb_pic, c->rgb_stride, c->pal, keyframe,
-                             ctx->split_position, 0,
-                             avctx->width, avctx->height))
-            return ret;
-        align_get_bits(&gb);
-
-        if (c->slice_split)
-            if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
-                                 c->rgb_pic, c->rgb_stride, c->pal, keyframe,
-                                 ctx->split_position, 1,
-                                 avctx->width, avctx->height))
-                return ret;
-
-        align_get_bits(&gb);
-        buf      += get_bits_count(&gb) >> 3;
-        buf_size -= get_bits_count(&gb) >> 3;
     } else {
         if (keyframe) {
             c->corrupted = 0;
@@ -676,32 +657,54 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
             if (c->slice_split)
                 ff_mss12_slicecontext_reset(&ctx->sc[1]);
         }
-        else if (c->corrupted)
-            return AVERROR_INVALIDDATA;
-        bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
-        arith2_init(&acoder, &gB);
-        c->keyframe = keyframe;
-        if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,
-                                                avctx->width,
-                                                ctx->split_position))
-            return AVERROR_INVALIDDATA;
+        if (is_rle) {
+            init_get_bits(&gb, buf, buf_size * 8);
+            if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
+                                 c->rgb_pic, c->rgb_stride, c->pal, keyframe,
+                                 ctx->split_position, 0,
+                                 avctx->width, avctx->height))
+                return ret;
+            align_get_bits(&gb);
 
-        buf      += arith2_get_consumed_bytes(&acoder);
-        buf_size -= arith2_get_consumed_bytes(&acoder);
-        if (c->slice_split) {
-            if (buf_size < 1)
+            if (c->slice_split)
+                if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
+                                     c->rgb_pic, c->rgb_stride, c->pal, keyframe,
+                                     ctx->split_position, 1,
+                                     avctx->width, avctx->height))
+                    return ret;
+
+            align_get_bits(&gb);
+            buf      += get_bits_count(&gb) >> 3;
+            buf_size -= get_bits_count(&gb) >> 3;
+        } else if (!implicit_rect || wmv9_mask != -1) {
+            if (c->corrupted)
                 return AVERROR_INVALIDDATA;
             bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
             arith2_init(&acoder, &gB);
-            if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,
-                                                    ctx->split_position,
+            c->keyframe = keyframe;
+            if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,
                                                     avctx->width,
-                                                    avctx->height - ctx->split_position))
+                                                    ctx->split_position))
                 return AVERROR_INVALIDDATA;
 
             buf      += arith2_get_consumed_bytes(&acoder);
             buf_size -= arith2_get_consumed_bytes(&acoder);
-        }
+            if (c->slice_split) {
+                if (buf_size < 1)
+                    return AVERROR_INVALIDDATA;
+                bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
+                arith2_init(&acoder, &gB);
+                if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,
+                                                        ctx->split_position,
+                                                        avctx->width,
+                                                        avctx->height - ctx->split_position))
+                    return AVERROR_INVALIDDATA;
+
+                buf      += arith2_get_consumed_bytes(&acoder);
+                buf_size -= arith2_get_consumed_bytes(&acoder);
+            }
+        } else
+            memset(c->pal_pic, 0, c->pal_stride * avctx->height);
     }
 
     if (has_wmv9) {
@@ -836,8 +839,8 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx)
     if (ret = ff_mss12_decode_init(c, 1, &ctx->sc[0], &ctx->sc[1]))
         return ret;
     c->pal_stride   = c->mask_stride;
-    c->pal_pic      = av_malloc(c->pal_stride * avctx->height);
-    c->last_pal_pic = av_malloc(c->pal_stride * avctx->height);
+    c->pal_pic      = av_mallocz(c->pal_stride * avctx->height);
+    c->last_pal_pic = av_mallocz(c->pal_stride * avctx->height);
     if (!c->pal_pic || !c->last_pal_pic) {
         mss2_decode_end(avctx);
         return AVERROR(ENOMEM);