]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/vc1dec: Postpone allocating sprite frame to avoid segfault
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Tue, 22 Dec 2020 16:21:48 +0000 (17:21 +0100)
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Wed, 24 Mar 2021 23:02:17 +0000 (00:02 +0100)
Up until now, the VC-1 decoders allocated an AVFrame for usage with
sprites during vc1_decode_init(); yet said AVFrame can be freed if
(re)initializing the context (which happens ordinarily during decoding)
fails. The AVFrame does not get allocated again lateron in this case,
leading to segfaults.

Fix this by moving the allocation of said frame immediately before it is
used (this also means that said frame won't be allocated at all any more
in case of a regular (i.e. non-image) stream).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
libavcodec/vc1dec.c

index 47940fb886eaac5a4b3791ed9cb1881a355c1015..b702b76060866d359bcc63e5fdcfeb9ad109bf81 100644 (file)
@@ -539,12 +539,6 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
     ff_h264chroma_init(&v->h264chroma, 8);
     ff_qpeldsp_init(&s->qdsp);
 
-    // Must happen after calling ff_vc1_decode_end
-    // to avoid de-allocating the sprite_output_frame
-    v->sprite_output_frame = av_frame_alloc();
-    if (!v->sprite_output_frame)
-        return AVERROR(ENOMEM);
-
     avctx->has_b_frames = !!avctx->max_b_frames;
 
     if (v->color_prim == 1 || v->color_prim == 5 || v->color_prim == 6)
@@ -577,20 +571,15 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
             v->sprite_height > 1 << 14 ||
             v->output_width  > 1 << 14 ||
             v->output_height > 1 << 14) {
-            ret = AVERROR_INVALIDDATA;
-            goto error;
+            return AVERROR_INVALIDDATA;
         }
 
         if ((v->sprite_width&1) || (v->sprite_height&1)) {
             avpriv_request_sample(avctx, "odd sprites support");
-            ret = AVERROR_PATCHWELCOME;
-            goto error;
+            return AVERROR_PATCHWELCOME;
         }
     }
     return 0;
-error:
-    av_frame_free(&v->sprite_output_frame);
-    return ret;
 }
 
 /** Close a VC1/WMV3 decoder
@@ -1147,6 +1136,11 @@ image:
         avctx->height = avctx->coded_height = v->output_height;
         if (avctx->skip_frame >= AVDISCARD_NONREF)
             goto end;
+        if (!v->sprite_output_frame &&
+            !(v->sprite_output_frame = av_frame_alloc())) {
+            ret = AVERROR(ENOMEM);
+            goto err;
+        }
 #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
         if ((ret = vc1_decode_sprites(v, &s->gb)) < 0)
             goto err;