diff options
author | Alex Converse <alex.converse@gmail.com> | 2012-01-25 16:12:42 -0800 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2012-04-01 18:33:26 +0200 |
commit | fd3af2950ace3b78e3003432873509dd3544f982 (patch) | |
tree | b4bb57724b709e914b3a74fbd5aaf26ee8fc6c86 | |
parent | 6c12293f6c3c91d5fbbb1146ad0f77b887abed48 (diff) | |
download | ffmpeg-fd3af2950ace3b78e3003432873509dd3544f982.tar.gz |
smacker: Sanity check huffman tables found in the headers.
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
(cherry picked from commit 9adf25c1cf78dbf1d71bf386c49dc74cb8a60df0)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: Reinhard Tartler <siretart@tauware.de>
-rw-r--r-- | libavcodec/smacker.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index fd88fd2c60..eb4427c100 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -127,12 +127,12 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref */ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) { + if (hc->current + 1 >= hc->length) { + av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); + return -1; + } if(!get_bits1(gb)){ //Leaf int val, i1, i2, b1, b2; - if(hc->current >= hc->length){ - av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); - return -1; - } b1 = get_bits_count(gb); i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0; b1 = get_bits_count(gb) - b1; @@ -156,7 +156,7 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx hc->values[hc->current++] = val; return 1; } else { //Node - int r = 0, t; + int r = 0, r_new, t; t = hc->current++; r = smacker_decode_bigtree(gb, hc, ctx); @@ -164,8 +164,10 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx return r; hc->values[t] = SMK_NODE | r; r++; - r += smacker_decode_bigtree(gb, hc, ctx); - return r; + r_new = smacker_decode_bigtree(gb, hc, ctx); + if (r_new < 0) + return r_new; + return r + r_new; } } @@ -180,6 +182,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int VLC vlc[2]; int escapes[3]; DBCtx ctx; + int err = 0; if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); @@ -253,7 +256,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); - smacker_decode_bigtree(gb, &huff, &ctx); + if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) + err = -1; skip_bits1(gb); if(ctx.last[0] == -1) ctx.last[0] = huff.current++; if(ctx.last[1] == -1) ctx.last[1] = huff.current++; @@ -272,7 +276,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int av_free(tmp2.lengths); av_free(tmp2.values); - return 0; + return err; } static int decode_header_trees(SmackVContext *smk) { |