return AVERROR_INVALIDDATA;
}
if(!get_bits1(gb)){ //Leaf
- if(hc->current >= 256){
+ if(hc->current >= hc->length){
av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n");
return AVERROR_INVALIDDATA;
}
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)) {
res = smacker_decode_tree(gb, &tmp1, 0, 0);
- if (res < 0)
- return res;
+ if (res < 0) {
+ err = res;
+ goto error;
+ }
skip_bits1(gb);
if(tmp1.current > 1) {
res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length,
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 AVERROR_INVALIDDATA;
+ err = res;
+ goto error;
}
}
}
}
if(get_bits1(gb)){
res = smacker_decode_tree(gb, &tmp2, 0, 0);
- if (res < 0)
- return res;
+ if (res < 0) {
+ err = res;
+ goto error;
+ }
skip_bits1(gb);
if(tmp2.current > 1) {
res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length,
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 AVERROR_INVALIDDATA;
+ err = res;
+ goto error;
}
}
}
huff.maxlength = 0;
huff.current = 0;
huff.values = av_mallocz(huff.length * sizeof(int));
- if (!huff.values)
- return AVERROR(ENOMEM);
+ if (!huff.values) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
if (smacker_decode_bigtree(gb, &huff, &ctx) < 0)
err = -1;
if(ctx.last[0] == -1) ctx.last[0] = huff.current++;
if(ctx.last[1] == -1) ctx.last[1] = huff.current++;
if(ctx.last[2] == -1) ctx.last[2] = huff.current++;
- if(huff.current > huff.length){
- ctx.last[0] = ctx.last[1] = ctx.last[2] = 1;
- av_log(smk->avctx, AV_LOG_ERROR, "bigtree damaged\n");
- return AVERROR_INVALIDDATA;
+ if (ctx.last[0] >= huff.length ||
+ ctx.last[1] >= huff.length ||
+ ctx.last[2] >= huff.length) {
+ av_log(smk->avctx, AV_LOG_ERROR, "Huffman codes out of range\n");
+ err = AVERROR_INVALIDDATA;
}
*recodes = huff.values;
+error:
if(vlc[0].table)
ff_free_vlc(&vlc[0]);
if(vlc[1].table)
full_size = AV_RL32(smk->avctx->extradata + 8);
type_size = AV_RL32(smk->avctx->extradata + 12);
- init_get_bits(&gb, smk->avctx->extradata + 16, (smk->avctx->extradata_size - 16) * 8);
+ init_get_bits8(&gb, smk->avctx->extradata + 16, smk->avctx->extradata_size - 16);
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 {
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 {
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 {
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 {
last_reset(smk->mclr_tbl, smk->mclr_last);
last_reset(smk->full_tbl, smk->full_last);
last_reset(smk->type_tbl, smk->type_last);
- init_get_bits(&gb, avpkt->data + 769, (avpkt->size - 769) * 8);
+ if ((ret = init_get_bits8(&gb, avpkt->data + 769, avpkt->size - 769)) < 0)
+ return ret;
blk = 0;
bw = avctx->width >> 2;
+/*
+ *
+ * Uninit smacker decoder
+ *
+ */
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ SmackVContext * const smk = avctx->priv_data;
+
+ av_freep(&smk->mmap_tbl);
+ av_freep(&smk->mclr_tbl);
+ av_freep(&smk->full_tbl);
+ av_freep(&smk->type_tbl);
+
+ av_frame_free(&smk->pic);
+
+ return 0;
+}
+
+
/*
*
* Init smacker decoder
}
ret = decode_header_trees(c);
- if (ret < 0)
+ if (ret < 0) {
+ decode_end(avctx);
return ret;
+ }
c->pic = av_frame_alloc();
if (!c->pic)
}
-
-/*
- *
- * Uninit smacker decoder
- *
- */
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- SmackVContext * const smk = avctx->priv_data;
-
- av_freep(&smk->mmap_tbl);
- av_freep(&smk->mclr_tbl);
- av_freep(&smk->full_tbl);
- av_freep(&smk->type_tbl);
-
- av_frame_free(&smk->pic);
-
- return 0;
-}
-
-
static av_cold int smka_decode_init(AVCodecContext *avctx)
{
if (avctx->channels < 1 || avctx->channels > 2) {
return AVERROR_INVALIDDATA;
}
- init_get_bits(&gb, buf + 4, (buf_size - 4) * 8);
+ if ((ret = init_get_bits8(&gb, buf + 4, buf_size - 4)) < 0)
+ return ret;
if(!get_bits1(&gb)){
av_log(avctx, AV_LOG_INFO, "Sound: no data\n");
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) {
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 AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto error;
}
}
}
}
}
+ *got_frame_ptr = 1;
+ ret = buf_size;
+
+error:
for(i = 0; i < 4; i++) {
if(vlc[i].table)
ff_free_vlc(&vlc[i]);
av_free(h[i].values);
}
- *got_frame_ptr = 1;
-
- return buf_size;
+ return ret;
}
AVCodec ff_smacker_decoder = {