#include "fmtconvert.h"
#include "sinewin.h"
#include "wma.h"
+#include "wma_common.h"
/** current decoder limitations */
#define WMAPRO_MAX_CHANNELS 8 ///< max number of handled channels
*@brief helper function to print the most important members of the context
*@param s context
*/
-static void av_cold dump_context(WMAProDecodeCtx *s)
+static av_cold void dump_context(WMAProDecodeCtx *s)
{
#define PRINT(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %d\n", a, b);
#define PRINT_HEX(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %x\n", a, b);
return AVERROR_INVALIDDATA;
}
+ if (s->min_samples_per_subframe < (1<<WMAPRO_BLOCK_MIN_BITS)) {
+ av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n",
+ s->min_samples_per_subframe);
+ return AVERROR_INVALIDDATA;
+ }
+
s->num_channels = avctx->channels;
if (s->num_channels < 0) {
*/
static int decode_tilehdr(WMAProDecodeCtx *s)
{
- uint16_t num_samples[WMAPRO_MAX_CHANNELS]; /**< sum of samples for all currently known subframes of a channel */
+ uint16_t num_samples[WMAPRO_MAX_CHANNELS] = { 0 };/**< sum of samples for all currently known subframes of a channel */
uint8_t contains_subframe[WMAPRO_MAX_CHANNELS]; /**< flag indicating if a channel contains the current subframe */
int channels_for_cur_subframe = s->num_channels; /**< number of channels that contain the current subframe */
int fixed_channel_layout = 0; /**< flag indicating that all channels use the same subframe offsets and sizes */
for (c = 0; c < s->num_channels; c++)
s->channel[c].num_subframes = 0;
- memset(num_samples, 0, sizeof(num_samples));
-
if (s->max_num_subframes == 1 || get_bits1(&s->gb))
fixed_channel_layout = 1;
int num_fill_bits;
if (!(num_fill_bits = get_bits(&s->gb, 2))) {
int len = get_bits(&s->gb, 4);
- num_fill_bits = get_bits(&s->gb, len) + 1;
+ num_fill_bits = (len ? get_bits(&s->gb, len) : 0) + 1;
}
if (num_fill_bits >= 0) {
transmit_coeffs = 1;
}
+ av_assert0(s->subframe_len <= WMAPRO_BLOCK_MAX_SIZE);
if (transmit_coeffs) {
int step;
int quant_step = 90 * s->bits_per_sample >> 4;
int num_bits = av_log2((s->subframe_len + 3)/4) + 1;
for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i];
- s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
+ int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
+ if (num_vec_coeffs > s->subframe_len) {
+ av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs);
+ return AVERROR_INVALIDDATA;
+ }
+ s->channel[c].num_vec_coeffs = num_vec_coeffs;
}
} else {
for (i = 0; i < s->channels_for_cur_subframe; i++) {
.close = decode_end,
.decode = decode_packet,
.capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
- .flush= flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
};