[FFmpeg-devel] avcodec/h264dec: Fix init_context memleak on error path

Submitted by Zhao Zhili on Sept. 5, 2018, 8:53 a.m.

Details

Message ID 20180905085344.17678-1-quinkblack@foxmail.com
State New
Headers show

Commit Message

Zhao Zhili Sept. 5, 2018, 8:53 a.m.
---
 libavcodec/h264dec.c | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

Comments

Zhao Zhili Sept. 10, 2018, 11:06 a.m.
Please review, thanks!

On 2018年09月05日 16:53, Zhao Zhili wrote:
> ---
>   libavcodec/h264dec.c | 28 ++++++++++++++++++++++------
>   1 file changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
> index 8d115fa..b2447e9 100644
> --- a/libavcodec/h264dec.c
> +++ b/libavcodec/h264dec.c
> @@ -303,6 +303,7 @@ fail:
>   static int h264_init_context(AVCodecContext *avctx, H264Context *h)
>   {
>       int i;
> +    int ret;
>   
>       h->avctx                 = avctx;
>       h->cur_chroma_format_idc = -1;
> @@ -337,22 +338,37 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
>   
>       for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) {
>           h->DPB[i].f = av_frame_alloc();
> -        if (!h->DPB[i].f)
> -            return AVERROR(ENOMEM);
> +        if (!h->DPB[i].f) {
> +            ret = AVERROR(ENOMEM);
> +            goto fail;
> +        }
>       }
>   
>       h->cur_pic.f = av_frame_alloc();
> -    if (!h->cur_pic.f)
> -        return AVERROR(ENOMEM);
> +    if (!h->cur_pic.f) {
> +        ret = AVERROR(ENOMEM);
> +        goto fail;
> +    }
>   
>       h->last_pic_for_ec.f = av_frame_alloc();
> -    if (!h->last_pic_for_ec.f)
> -        return AVERROR(ENOMEM);
> +    if (!h->last_pic_for_ec.f) {
> +        ret = AVERROR(ENOMEM);
> +        goto fail;
> +    }
>   
>       for (i = 0; i < h->nb_slice_ctx; i++)
>           h->slice_ctx[i].h264 = h;
>   
>       return 0;
> +
> +fail:
> +    h->nb_slice_ctx = 0;
> +    av_freep(&h->slice_ctx);
> +    for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) {
> +        av_frame_free(&h->DPB[i].f);
> +    }
> +    av_frame_free(&h->cur_pic.f);
> +    return ret;
>   }
>   
>   static av_cold int h264_decode_end(AVCodecContext *avctx)

Patch hide | download patch | download mbox

diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 8d115fa..b2447e9 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -303,6 +303,7 @@  fail:
 static int h264_init_context(AVCodecContext *avctx, H264Context *h)
 {
     int i;
+    int ret;
 
     h->avctx                 = avctx;
     h->cur_chroma_format_idc = -1;
@@ -337,22 +338,37 @@  static int h264_init_context(AVCodecContext *avctx, H264Context *h)
 
     for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) {
         h->DPB[i].f = av_frame_alloc();
-        if (!h->DPB[i].f)
-            return AVERROR(ENOMEM);
+        if (!h->DPB[i].f) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
     }
 
     h->cur_pic.f = av_frame_alloc();
-    if (!h->cur_pic.f)
-        return AVERROR(ENOMEM);
+    if (!h->cur_pic.f) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
 
     h->last_pic_for_ec.f = av_frame_alloc();
-    if (!h->last_pic_for_ec.f)
-        return AVERROR(ENOMEM);
+    if (!h->last_pic_for_ec.f) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
 
     for (i = 0; i < h->nb_slice_ctx; i++)
         h->slice_ctx[i].h264 = h;
 
     return 0;
+
+fail:
+    h->nb_slice_ctx = 0;
+    av_freep(&h->slice_ctx);
+    for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) {
+        av_frame_free(&h->DPB[i].f);
+    }
+    av_frame_free(&h->cur_pic.f);
+    return ret;
 }
 
 static av_cold int h264_decode_end(AVCodecContext *avctx)