summaryrefslogtreecommitdiff
path: root/libavcodec/smacker.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2013-09-11 15:35:19 +0300
committerMartin Storsjö <martin@martin.st>2013-09-11 20:20:28 +0300
commitd002fce24a7206e95f9492031f45adc35711e183 (patch)
tree41734f12ad01d0c35a28399d5794005086ae0ccb /libavcodec/smacker.c
parent710b0e27025948b7511821c2f888ff2d74a59e14 (diff)
smacker: Check malloc return values
Also try to free local allocations on errors. Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavcodec/smacker.c')
-rw-r--r--libavcodec/smacker.c49
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 = {