diff options
author | Lukasz Marek <lukasz.m.luki2@gmail.com> | 2014-11-23 00:57:33 +0100 |
---|---|---|
committer | Lukasz Marek <lukasz.m.luki2@gmail.com> | 2014-11-24 04:15:48 +0100 |
commit | c9d39fc8c68700832d5206e40d12761d65a604de (patch) | |
tree | 656eceefa0e6c76cae012fb21aa05d9a3eab6bc7 /libavcodec/huffyuvdec.c | |
parent | 02cb7d4c9c3adfae84ef0d5646c2de944176f849 (diff) | |
download | ffmpeg-c9d39fc8c68700832d5206e40d12761d65a604de.tar.gz |
lavc/huffyuvdec: fix mem leak in case of init failure
Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
Diffstat (limited to 'libavcodec/huffyuvdec.c')
-rw-r--r-- | libavcodec/huffyuvdec.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index 3b2b0f7f59..62ed0f97b1 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -272,6 +272,20 @@ static int read_old_huffman_tables(HYuvContext *s) return 0; } +static av_cold int decode_end(AVCodecContext *avctx) +{ + HYuvContext *s = avctx->priv_data; + int i; + + ff_huffyuv_common_end(s); + av_freep(&s->bitstream_buffer); + + for (i = 0; i < 8; i++) + ff_free_vlc(&s->vlc[i]); + + return 0; +} + static av_cold int decode_init(AVCodecContext *avctx) { HYuvContext *s = avctx->priv_data; @@ -327,7 +341,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if ((ret = read_huffman_tables(s, avctx->extradata + 4, avctx->extradata_size - 4)) < 0) - return ret; + goto error; } else { switch (avctx->bits_per_coded_sample & 7) { case 1: @@ -355,7 +369,7 @@ static av_cold int decode_init(AVCodecContext *avctx) s->context = 0; if ((ret = read_old_huffman_tables(s)) < 0) - return ret; + goto error; } if (s->version <= 2) { @@ -383,7 +397,8 @@ static av_cold int decode_init(AVCodecContext *avctx) s->alpha = 1; break; default: - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto error; } av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, @@ -520,7 +535,8 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUVA420P16; break; default: - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto error; } } @@ -528,21 +544,26 @@ static av_cold int decode_init(AVCodecContext *avctx) if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P || avctx->pix_fmt == AV_PIX_FMT_YUV420P) && avctx->width & 1) { av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto error; } if (s->predictor == MEDIAN && avctx->pix_fmt == AV_PIX_FMT_YUV422P && avctx->width % 4) { av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 4 " "for this combination of colorspace and predictor type.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto error; } if ((ret = ff_huffyuv_alloc_temp(s)) < 0) { ff_huffyuv_common_end(s); - return ret; + goto error; } return 0; + error: + decode_end(avctx); + return ret; } static av_cold int decode_init_thread_copy(AVCodecContext *avctx) @@ -1209,20 +1230,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return (get_bits_count(&s->gb) + 31) / 32 * 4 + table_size; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - HYuvContext *s = avctx->priv_data; - int i; - - ff_huffyuv_common_end(s); - av_freep(&s->bitstream_buffer); - - for (i = 0; i < 8; i++) - ff_free_vlc(&s->vlc[i]); - - return 0; -} - AVCodec ff_huffyuv_decoder = { .name = "huffyuv", .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), |