diff options
author | Martin Storsjö <martin@martin.st> | 2013-09-11 16:35:19 +0400 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2013-09-11 21:20:28 +0400 |
commit | d002fce24a7206e95f9492031f45adc35711e183 (patch) | |
tree | 41734f12ad01d0c35a28399d5794005086ae0ccb | |
parent | 710b0e27025948b7511821c2f888ff2d74a59e14 (diff) |
smacker: Check malloc return values
Also try to free local allocations on errors.
Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r-- | libavcodec/smacker.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 5f84c50ec8..d33c223dcf 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -200,6 +200,11 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int tmp2.bits = av_mallocz(256 * 4); tmp2.lengths = av_mallocz(256 * sizeof(int)); tmp2.values = av_mallocz(256 * sizeof(int)); + if (!tmp1.bits || !tmp1.lengths || !tmp1.values || + !tmp2.bits || !tmp2.lengths || !tmp2.values) { + err = AVERROR(ENOMEM); + goto error; + } if(get_bits1(gb)) { smacker_decode_tree(gb, &tmp1, 0, 0); @@ -209,7 +214,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return -1; + err = res; + goto error; } } else { av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n"); @@ -222,7 +228,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return -1; + err = res; + goto error; } } else { av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n"); @@ -250,6 +257,10 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int huff.maxlength = 0; huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); + if (!huff.values) { + err = AVERROR(ENOMEM); + goto error; + } if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) err = -1; @@ -260,6 +271,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int *recodes = huff.values; +error: if(vlc[0].table) ff_free_vlc(&vlc[0]); if(vlc[1].table) @@ -288,6 +300,8 @@ static int decode_header_trees(SmackVContext *smk) { if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n"); smk->mmap_tbl = av_malloc(sizeof(int) * 2); + if (!smk->mmap_tbl) + return AVERROR(ENOMEM); smk->mmap_tbl[0] = 0; smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; } else { @@ -297,6 +311,8 @@ static int decode_header_trees(SmackVContext *smk) { if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); smk->mclr_tbl = av_malloc(sizeof(int) * 2); + if (!smk->mclr_tbl) + return AVERROR(ENOMEM); smk->mclr_tbl[0] = 0; smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; } else { @@ -306,6 +322,8 @@ static int decode_header_trees(SmackVContext *smk) { if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); smk->full_tbl = av_malloc(sizeof(int) * 2); + if (!smk->full_tbl) + return AVERROR(ENOMEM); smk->full_tbl[0] = 0; smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; } else { @@ -315,6 +333,8 @@ static int decode_header_trees(SmackVContext *smk) { if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); smk->type_tbl = av_malloc(sizeof(int) * 2); + if (!smk->type_tbl) + return AVERROR(ENOMEM); smk->type_tbl[0] = 0; smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; } else { @@ -628,16 +648,14 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); + if (!h[i].bits || !h[i].lengths || !h[i].values) { + ret = AVERROR(ENOMEM); + goto error; + } skip_bits1(&gb); if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { - for (; i >= 0; i--) { - if (vlc[i].table) - ff_free_vlc(&vlc[i]); - av_free(h[i].bits); - av_free(h[i].lengths); - av_free(h[i].values); - } - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto error; } skip_bits1(&gb); if(h[i].current > 1) { @@ -646,7 +664,8 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return -1; + ret = AVERROR_INVALIDDATA; + goto error; } } } @@ -709,6 +728,10 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, } } + *got_frame_ptr = 1; + ret = buf_size; + +error: for(i = 0; i < 4; i++) { if(vlc[i].table) ff_free_vlc(&vlc[i]); @@ -717,9 +740,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, av_free(h[i].values); } - *got_frame_ptr = 1; - - return buf_size; + return ret; } AVCodec ff_smacker_decoder = { |