X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fqdm2.c;h=657b2da64dc8fa2721f37b25a70cf43e6f31bd88;hb=1ab3ae6fd5b1866aa42cfc0c5d79700adb7281d8;hp=88b6b19d1123716a9dac520b6ef6079a8b20bac2;hpb=06476249cd2332e30b66576633b2827adf3478dd;p=ffmpeg diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 88b6b19d112..657b2da64dc 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -408,7 +408,12 @@ static int fix_coding_method_array(int sb, int channels, } for (k = 0; k < run; k++) { if (j + k < 128) { - if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) { + int sbjk = sb + (j + k) / 64; + if (sbjk > 29) { + SAMPLES_NEEDED + continue; + } + if (coding_method[ch][sbjk][(j + k) % 64] > coding_method[ch][sb][j]) { if (k > 0) { SAMPLES_NEEDED //not debugged, almost never used @@ -1284,6 +1289,10 @@ static void qdm2_fft_decode_tones(QDM2Context *q, int duration, } offset += (n - 2); } else { + if (local_int_10 <= 2) { + av_log(NULL, AV_LOG_ERROR, "qdm2_fft_decode_tones() stuck\n"); + return; + } offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); while (offset >= (local_int_10 - 1)) { offset += (1 - (local_int_10 - 1)); @@ -1325,6 +1334,9 @@ static void qdm2_fft_decode_tones(QDM2Context *q, int duration, if (q->frequency_range > (local_int_14 + 1)) { int sub_packet = (local_int_20 + local_int_28); + if (q->fft_coefs_index + stereo >= FF_ARRAY_ELEMS(q->fft_coefs)) + return; + qdm2_fft_init_coefficient(q, sub_packet, offset, duration, channel, exp, phase); if (stereo) @@ -1695,13 +1707,19 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) s->group_size = bytestream2_get_be32(&gb); s->fft_size = bytestream2_get_be32(&gb); s->checksum_size = bytestream2_get_be32(&gb); - if (s->checksum_size >= 1U << 28) { - av_log(avctx, AV_LOG_ERROR, "data block size too large (%u)\n", s->checksum_size); + if (s->checksum_size >= 1U << 28 || s->checksum_size <= 1) { + av_log(avctx, AV_LOG_ERROR, "data block size invalid (%u)\n", s->checksum_size); return AVERROR_INVALIDDATA; } s->fft_order = av_log2(s->fft_size) + 1; + // Fail on unknown fft order + if ((s->fft_order < 7) || (s->fft_order > 9)) { + avpriv_request_sample(avctx, "Unknown FFT order %d", s->fft_order); + return AVERROR_PATCHWELCOME; + } + // something like max decodable tones s->group_order = av_log2(s->group_size) + 1; s->frame_size = s->group_size / 16; // 16 iterations per super block @@ -1712,6 +1730,11 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) s->sub_sampling = s->fft_order - 7; s->frequency_range = 255 / (1 << (2 - s->sub_sampling)); + if (s->frame_size * 4 >> s->sub_sampling > MPA_FRAME_SIZE) { + avpriv_request_sample(avctx, "large frames"); + return AVERROR_PATCHWELCOME; + } + switch ((s->sub_sampling * 2 + s->channels - 1)) { case 0: tmp = 40; break; case 1: tmp = 48; break; @@ -1735,11 +1758,6 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) else s->coeff_per_sb_select = 2; - // Fail on unknown fft order - if ((s->fft_order < 7) || (s->fft_order > 9)) { - avpriv_request_sample(avctx, "Unknown FFT order %d", s->fft_order); - return AVERROR_PATCHWELCOME; - } if (s->fft_size != (1 << (s->fft_order - 1))) { av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size); return AVERROR_INVALIDDATA;