X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fwmaprodec.c;h=8024ce1611548eba147808dafd3e2e08b040d335;hb=339af976b6fd9c05d1e75e75a5323efdb3d6afa1;hp=87e2ead693fb081b2fbf454b98411550434554cb;hpb=589cb44498b5e9683c95746255a2abd6d1e74f94;p=ffmpeg diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 87e2ead693f..8024ce16115 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -92,6 +92,8 @@ #include "libavutil/float_dsp.h" #include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" + #include "avcodec.h" #include "internal.h" #include "get_bits.h" @@ -544,7 +546,7 @@ static av_cold int decode_init(WMAProDecodeCtx *s, AVCodecContext *avctx, int nu for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) ff_mdct_init(&s->mdct_ctx[i], WMAPRO_BLOCK_MIN_BITS+1+i, 1, 1.0 / (1 << (WMAPRO_BLOCK_MIN_BITS + i - 1)) - / (1 << (s->bits_per_sample - 1))); + / (1ll << (s->bits_per_sample - 1))); /** init MDCT windows: simple sine window */ for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) { @@ -1579,14 +1581,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, s->num_saved_bits += len; if (!append) { - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), + ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), s->num_saved_bits); } else { int align = 8 - (get_bits_count(gb) & 7); align = FFMIN(align, len); put_bits(&s->pb, align, get_bits(gb, align)); len -= align; - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); + ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); } skip_bits_long(gb, len); @@ -1644,6 +1646,7 @@ static int decode_packet(AVCodecContext *avctx, WMAProDecodeCtx *s, if (avctx->codec_id == AV_CODEC_ID_WMAPRO && buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, "Input packet too small (%d < %d)\n", buf_size, avctx->block_align); + s->packet_loss = 1; return AVERROR_INVALIDDATA; } @@ -1718,6 +1721,12 @@ static int decode_packet(AVCodecContext *avctx, WMAProDecodeCtx *s, } } else { int frame_size; + + if (avpkt->size < s->next_packet_start) { + s->packet_loss = 1; + return AVERROR_INVALIDDATA; + } + s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3; init_get_bits(gb, avpkt->data, s->buf_bit_size); skip_bits(gb, s->packet_offset); @@ -1803,6 +1812,11 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data, ret = decode_packet(avctx, &s->xma[s->current_stream], s->frames[s->current_stream], &got_stream_frame_ptr, avpkt); + if (got_stream_frame_ptr && s->offset[s->current_stream] >= 64) { + got_stream_frame_ptr = 0; + ret = AVERROR_INVALIDDATA; + } + /* copy stream samples (1/2ch) to sample buffer (Nch) */ if (got_stream_frame_ptr) { int start_ch = s->start_channel[s->current_stream]; @@ -1930,6 +1944,8 @@ static av_cold int xma_decode_init(AVCodecContext *avctx) s->start_channel[i] = start_channels; start_channels += s->xma[i].nb_channels; } + if (start_channels != avctx->channels) + return AVERROR_INVALIDDATA; return ret; }