avcodec/wmadec: fix 0 frame bit_reservoir
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 12 Jan 2015 00:51:06 +0000 (01:51 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 12 Jan 2015 02:33:16 +0000 (03:33 +0100)
Fixes Ticket968
partly fixes Ticket691

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/wma.h
libavcodec/wmadec.c

index a232b8a..8d337df 100644 (file)
@@ -42,7 +42,7 @@
 #define NB_LSP_COEFS 10
 
 /* XXX: is it a suitable value ? */
-#define MAX_CODED_SUPERFRAME_SIZE 16384
+#define MAX_CODED_SUPERFRAME_SIZE 32768
 
 #define MAX_CHANNELS 2
 
index b7fa070..79e7b0c 100644 (file)
@@ -840,9 +840,29 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data,
         skip_bits(&s->gb, 4); /* super frame index */
         nb_frames = get_bits(&s->gb, 4) - (s->last_superframe_len <= 0);
         if (nb_frames <= 0) {
-            av_log(avctx, AV_LOG_ERROR, "nb_frames is %d bits left %d\n",
+            int is_error = nb_frames < 0 || get_bits_left(&s->gb) <= 8;
+            av_log(avctx, is_error ? AV_LOG_ERROR : AV_LOG_WARNING,
+                   "nb_frames is %d bits left %d\n",
                    nb_frames, get_bits_left(&s->gb));
-            return AVERROR_INVALIDDATA;
+            if (is_error)
+                return AVERROR_INVALIDDATA;
+
+            if ((s->last_superframe_len + buf_size - 1) >
+                MAX_CODED_SUPERFRAME_SIZE)
+                goto fail;
+
+            q   = s->last_superframe + s->last_superframe_len;
+            len = buf_size - 1;
+            while (len > 0) {
+                *q++ = get_bits (&s->gb, 8);
+                len --;
+            }
+            memset(q, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+            s->last_superframe_len += 8*buf_size - 8;
+//             s->reset_block_lengths = 1; //XXX is this needed ?
+            *got_frame_ptr = 0;
+            return buf_size;
         }
     } else
         nb_frames = 1;