|
@@ -153,11 +153,18 @@ static const uint8_t rle_length_tab[16] = {
|
|
|
2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
|
|
|
};
|
|
|
|
|
|
+#define GET_BITS_SAFE(out, nbits) do { \
|
|
|
+ if (get_bits_left(gb) < nbits) \
|
|
|
+ return AVERROR_INVALIDDATA; \
|
|
|
+ out = get_bits(gb, nbits); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
/**
|
|
|
* Decode Bink Audio block
|
|
|
* @param[out] out Output buffer (must contain s->block_size elements)
|
|
|
+ * @return 0 on success, negative error code on failure
|
|
|
*/
|
|
|
-static void decode_block(BinkAudioContext *s, short *out, int use_dct)
|
|
|
+static int decode_block(BinkAudioContext *s, short *out, int use_dct)
|
|
|
{
|
|
|
int ch, i, j, k;
|
|
|
float q, quant[25];
|
|
@@ -170,13 +177,19 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
|
|
|
for (ch = 0; ch < s->channels; ch++) {
|
|
|
FFTSample *coeffs = s->coeffs_ptr[ch];
|
|
|
if (s->version_b) {
|
|
|
+ if (get_bits_left(gb) < 64)
|
|
|
+ return AVERROR_INVALIDDATA;
|
|
|
coeffs[0] = av_int2flt(get_bits(gb, 32)) * s->root;
|
|
|
coeffs[1] = av_int2flt(get_bits(gb, 32)) * s->root;
|
|
|
} else {
|
|
|
+ if (get_bits_left(gb) < 58)
|
|
|
+ return AVERROR_INVALIDDATA;
|
|
|
coeffs[0] = get_float(gb) * s->root;
|
|
|
coeffs[1] = get_float(gb) * s->root;
|
|
|
}
|
|
|
|
|
|
+ if (get_bits_left(gb) < s->num_bands * 8)
|
|
|
+ return AVERROR_INVALIDDATA;
|
|
|
for (i = 0; i < s->num_bands; i++) {
|
|
|
/* constant is result of 0.066399999/log10(M_E) */
|
|
|
int value = get_bits(gb, 8);
|
|
@@ -191,15 +204,20 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
|
|
|
while (i < s->frame_len) {
|
|
|
if (s->version_b) {
|
|
|
j = i + 16;
|
|
|
- } else if (get_bits1(gb)) {
|
|
|
- j = i + rle_length_tab[get_bits(gb, 4)] * 8;
|
|
|
} else {
|
|
|
- j = i + 8;
|
|
|
+ int v;
|
|
|
+ GET_BITS_SAFE(v, 1);
|
|
|
+ if (v) {
|
|
|
+ GET_BITS_SAFE(v, 4);
|
|
|
+ j = i + rle_length_tab[v] * 8;
|
|
|
+ } else {
|
|
|
+ j = i + 8;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
j = FFMIN(j, s->frame_len);
|
|
|
|
|
|
- width = get_bits(gb, 4);
|
|
|
+ GET_BITS_SAFE(width, 4);
|
|
|
if (width == 0) {
|
|
|
memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
|
|
|
i = j;
|
|
@@ -209,9 +227,11 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
|
|
|
while (i < j) {
|
|
|
if (s->bands[k] == i)
|
|
|
q = quant[k++];
|
|
|
- coeff = get_bits(gb, width);
|
|
|
+ GET_BITS_SAFE(coeff, width);
|
|
|
if (coeff) {
|
|
|
- if (get_bits1(gb))
|
|
|
+ int v;
|
|
|
+ GET_BITS_SAFE(v, 1);
|
|
|
+ if (v)
|
|
|
coeffs[i] = -q * coeff;
|
|
|
else
|
|
|
coeffs[i] = q * coeff;
|
|
@@ -247,6 +267,8 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
|
|
|
s->overlap_len * s->channels * sizeof(*out));
|
|
|
|
|
|
s->first = 0;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static av_cold int decode_end(AVCodecContext *avctx)
|
|
@@ -278,12 +300,17 @@ static int decode_frame(AVCodecContext *avctx,
|
|
|
int reported_size;
|
|
|
GetBitContext *gb = &s->gb;
|
|
|
|
|
|
+ if (buf_size < 4) {
|
|
|
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
|
|
|
+ return AVERROR_INVALIDDATA;
|
|
|
+ }
|
|
|
+
|
|
|
init_get_bits(gb, buf, buf_size * 8);
|
|
|
|
|
|
reported_size = get_bits_long(gb, 32);
|
|
|
- while (get_bits_count(gb) / 8 < buf_size &&
|
|
|
- samples + s->block_size <= samples_end) {
|
|
|
- decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT);
|
|
|
+ while (samples + s->block_size <= samples_end) {
|
|
|
+ if (decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT))
|
|
|
+ break;
|
|
|
samples += s->block_size;
|
|
|
get_bits_align32(gb);
|
|
|
}
|