Merge remote-tracking branch 'qatar/release/0.5' into release/0.5

* qatar/release/0.5:
  Bump version number for 0.5.6 release.
  svq1dec: call avcodec_set_dimensions() after dimensions changed.
  vmd: fix segfaults on corruped streams
  vp6: partially propagate huffman tree building errors during coeff model parsing and fix misspelling
  Plug some memory leaks in the VP6 decoder
  vp6: Reset the internal state when aborting key frames header parsing
  vp6: Fix illegal read.
  vp6: Fix illegal read.
  Fix out of bound reads in the QDM2 decoder.
  Check for out of bound writes in the QDM2 decoder.
  qdm2: check output buffer size before decoding
  Fix qdm2 decoder packet handling to match the api

Conflicts:
	libavcodec/qdm2.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index f9fed4f..8567ea8 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1378,6 +1378,8 @@
             return;
 
         local_int_14 = (offset >> local_int_8);
+        if (local_int_14 >= FF_ARRAY_ELEMS(fft_level_index_table))
+            return;
 
         if (q->nb_channels > 1) {
             channel = get_bits1(gb);
@@ -1912,7 +1914,7 @@
 }
 
 
-static void qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out)
+static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out)
 {
     int ch, i;
     const int frame_size = (q->frame_size * q->channels);
@@ -1951,7 +1953,7 @@
 
         if (!q->has_errors && q->sub_packet_list_C[0].packet != NULL) {
             SAMPLES_NEEDED_2("has errors, and C list is not empty")
-            return;
+            return -1;
         }
     }
 
@@ -1972,6 +1974,8 @@
 
         out[i] = value;
     }
+
+    return 0;
 }
 
 
@@ -1980,25 +1984,33 @@
             const uint8_t *buf, int buf_size)
 {
     QDM2Context *s = avctx->priv_data;
+    int16_t *out = data;
+    int i, out_size;
 
     if(!buf)
         return 0;
     if(buf_size < s->checksum_size)
         return -1;
 
-    *data_size = s->channels * s->frame_size * sizeof(int16_t);
+    out_size = 16 * s->channels * s->frame_size *
+               av_get_bits_per_sample_format(avctx->sample_fmt)/8;
+    if (*data_size < out_size) {
+        av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
+        return AVERROR(EINVAL);
+    }
 
     av_log(avctx, AV_LOG_DEBUG, "decode(%d): %p[%d] -> %p[%d]\n",
        buf_size, buf, s->checksum_size, data, *data_size);
 
-    qdm2_decode(s, buf, data);
-
-    // reading only when next superblock found
-    if (s->sub_packet == 0) {
-        return s->checksum_size;
+    for (i = 0; i < 16; i++) {
+        if (qdm2_decode(s, buf, out) < 0)
+            return -1;
+        out += s->channels * s->frame_size;
     }
 
-    return 0;
+    *data_size = out_size;
+
+    return buf_size;
 }
 
 AVCodec qdm2_decoder =
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index a63afb0..60dc7f9 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -73,9 +73,11 @@
 #define QUEUE_SIZE 0x1000
 #define QUEUE_MASK 0x0FFF
 
-static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len)
+static void lz_unpack(const unsigned char *src, int src_len,
+                      unsigned char *dest, int dest_len)
 {
     const unsigned char *s;
+    unsigned int s_len;
     unsigned char *d;
     unsigned char *d_end;
     unsigned char queue[QUEUE_SIZE];
@@ -88,13 +90,16 @@
     unsigned int i, j;
 
     s = src;
+    s_len = src_len;
     d = dest;
     d_end = d + dest_len;
     dataleft = AV_RL32(s);
-    s += 4;
+    s += 4; s_len -= 4;
     memset(queue, 0x20, QUEUE_SIZE);
+    if (s_len < 4)
+        return;
     if (AV_RL32(s) == 0x56781234) {
-        s += 4;
+        s += 4; s_len -= 4;
         qpos = 0x111;
         speclen = 0xF + 3;
     } else {
@@ -102,32 +107,41 @@
         speclen = 100;  /* no speclen */
     }
 
-    while (dataleft > 0) {
-        tag = *s++;
+    while (dataleft > 0 && s_len > 0) {
+        tag = *s++; s_len--;
         if ((tag == 0xFF) && (dataleft > 8)) {
-            if (d + 8 > d_end)
+            if (d + 8 > d_end || s_len < 8)
                 return;
             for (i = 0; i < 8; i++) {
                 queue[qpos++] = *d++ = *s++;
                 qpos &= QUEUE_MASK;
             }
+            s_len -= 8;
             dataleft -= 8;
         } else {
             for (i = 0; i < 8; i++) {
                 if (dataleft == 0)
                     break;
                 if (tag & 0x01) {
-                    if (d + 1 > d_end)
+                    if (d + 1 > d_end || s_len < 1)
                         return;
                     queue[qpos++] = *d++ = *s++;
                     qpos &= QUEUE_MASK;
                     dataleft--;
+                    s_len--;
                 } else {
+                    if (s_len < 2)
+                        return;
                     chainofs = *s++;
                     chainofs |= ((*s & 0xF0) << 4);
                     chainlen = (*s++ & 0x0F) + 3;
-                    if (chainlen == speclen)
+                    s_len -= 2;
+                    if (chainlen == speclen) {
+                        if (s_len < 1)
+                            return;
                         chainlen = *s++ + 0xF + 3;
+                        s_len--;
+                    }
                     if (d + chainlen > d_end)
                         return;
                     for (j = 0; j < chainlen; j++) {
@@ -144,7 +158,7 @@
 }
 
 static int rle_unpack(const unsigned char *src, unsigned char *dest,
-    int src_len, int dest_len)
+    int src_count, int src_size, int dest_len)
 {
     const unsigned char *ps;
     unsigned char *pd;
@@ -153,31 +167,40 @@
 
     ps = src;
     pd = dest;
-    if (src_len & 1)
+    if (src_count & 1) {
+        if (src_size < 1)
+            return 0;
         *pd++ = *ps++;
+        src_size--;
+    }
 
-    src_len >>= 1;
+    src_count >>= 1;
     i = 0;
     do {
+        if (src_size < 1)
+            break;
         l = *ps++;
+        src_size--;
         if (l & 0x80) {
             l = (l & 0x7F) * 2;
-            if (pd + l > dest_end)
+            if (pd + l > dest_end || src_size < l)
                 return ps - src;
             memcpy(pd, ps, l);
             ps += l;
+            src_size -= l;
             pd += l;
         } else {
-            if (pd + i > dest_end)
+            if (pd + i > dest_end || src_size < 2)
                 return ps - src;
             for (i = 0; i < l; i++) {
                 *pd++ = ps[0];
                 *pd++ = ps[1];
             }
             ps += 2;
+            src_size -= 2;
         }
         i += l;
-    } while (i < src_len);
+    } while (i < src_count);
 
     return ps - src;
 }
@@ -192,6 +215,7 @@
     const unsigned char *p = s->buf + 16;
 
     const unsigned char *pb;
+    unsigned int pb_size;
     unsigned char meth;
     unsigned char *dp;   /* pointer to current frame */
     unsigned char *pp;   /* pointer to previous frame */
@@ -228,8 +252,9 @@
 
     /* if only a certain region will be updated, copy the entire previous
      * frame before the decode */
-    if (frame_x || frame_y || (frame_width != s->avctx->width) ||
-        (frame_height != s->avctx->height)) {
+    if (s->prev_frame.data[0] &&
+        (frame_x || frame_y || (frame_width != s->avctx->width) ||
+        (frame_height != s->avctx->height))) {
 
         memcpy(s->frame.data[0], s->prev_frame.data[0],
             s->avctx->height * s->frame.linesize[0]);
@@ -247,14 +272,19 @@
         }
         s->size -= (256 * 3 + 2);
     }
-    if (s->size >= 0) {
+    if (s->size > 0) {
         /* originally UnpackFrame in VAG's code */
         pb = p;
-        meth = *pb++;
+        pb_size = s->buf + s->size - pb;
+        if (pb_size < 1)
+            return;
+        meth = *pb++; pb_size--;
         if (meth & 0x80) {
-            lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
+            lz_unpack(pb, pb_size,
+                      s->unpack_buffer, s->unpack_buffer_size);
             meth &= 0x7F;
             pb = s->unpack_buffer;
+            pb_size = s->unpack_buffer_size;
         }
 
         dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
@@ -265,17 +295,21 @@
             for (i = 0; i < frame_height; i++) {
                 ofs = 0;
                 do {
+                    if (pb_size < 1)
+                        return;
                     len = *pb++;
+                    pb_size--;
                     if (len & 0x80) {
                         len = (len & 0x7F) + 1;
-                        if (ofs + len > frame_width)
+                        if (ofs + len > frame_width || pb_size < len)
                             return;
                         memcpy(&dp[ofs], pb, len);
                         pb += len;
+                        pb_size -= len;
                         ofs += len;
                     } else {
                         /* interframe pixel copy */
-                        if (ofs + len + 1 > frame_width)
+                        if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
                             return;
                         memcpy(&dp[ofs], &pp[ofs], len + 1);
                         ofs += len + 1;
@@ -293,8 +327,11 @@
 
         case 2:
             for (i = 0; i < frame_height; i++) {
+                if (pb_size < frame_width)
+                    return;
                 memcpy(dp, pb, frame_width);
                 pb += frame_width;
+                pb_size -= frame_width;
                 dp += s->frame.linesize[0];
                 pp += s->prev_frame.linesize[0];
             }
@@ -304,18 +341,27 @@
             for (i = 0; i < frame_height; i++) {
                 ofs = 0;
                 do {
+                    if (pb_size < 1)
+                        return;
                     len = *pb++;
+                    pb_size--;
                     if (len & 0x80) {
                         len = (len & 0x7F) + 1;
+                        if (pb_size < 1)
+                            return;
                         if (*pb++ == 0xFF)
-                            len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
-                        else
+                            len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs);
+                        else {
+                            if (pb_size < len)
+                                return;
                             memcpy(&dp[ofs], pb, len);
+                        }
                         pb += len;
+                        pb_size -= 1 + len;
                         ofs += len;
                     } else {
                         /* interframe pixel copy */
-                        if (ofs + len + 1 > frame_width)
+                        if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
                             return;
                         memcpy(&dp[ofs], &pp[ofs], len + 1);
                         ofs += len + 1;
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index 65ddb8b..1ca8a40 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -695,6 +695,7 @@
 av_cold int vp56_free(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
+    int pt;
 
     av_free(s->above_blocks);
     av_free(s->macroblocks);
@@ -705,5 +706,15 @@
         avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]);
     if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
         avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
+
+    for (pt=0; pt < 2; pt++) {
+        int ct, cg;
+        free_vlc(&s->dccv_vlc[pt]);
+        free_vlc(&s->runv_vlc[pt]);
+        for (ct=0; ct<3; ct++)
+            for (cg = 0; cg < 6; cg++)
+                free_vlc(&s->ract_vlc[pt][ct][cg]);
+    }
+
     return 0;
 }
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index b89ff49..d9e9711 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -136,8 +136,11 @@
     if (coeff_offset) {
         buf      += coeff_offset;
         buf_size -= coeff_offset;
-        if (buf_size < 0)
+        if (buf_size < 0) {
+            if (s->framep[VP56_FRAME_CURRENT]->key_frame)
+                avcodec_set_dimensions(s->avctx, 0, 0);
             return 0;
+        }
         if (s->use_huffman) {
             s->parse_coeff = vp6_parse_coeff_huffman;
             init_get_bits(&s->gb, buf, buf_size<<3);
@@ -212,8 +215,8 @@
     return (a->count - b->count)*16 + (b->sym - a->sym);
 }
 
-static void vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[],
-                                const uint8_t *map, unsigned size, VLC *vlc)
+static int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[],
+                               const uint8_t *map, unsigned size, VLC *vlc)
 {
     Node nodes[2*size], *tmp = &nodes[size];
     int a, b, i;
@@ -227,9 +230,10 @@
         nodes[map[2*i+1]].count = b + !b;
     }
 
-    /* then build the huffman tree accodring to probabilities */
-    ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp,
-                       FF_HUFFMAN_FLAG_HNODE_FIRST);
+    free_vlc(vlc);
+    /* then build the huffman tree according to probabilities */
+    return ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp,
+                              FF_HUFFMAN_FLAG_HNODE_FIRST);
 }
 
 static void vp6_parse_coeff_models(VP56Context *s)
@@ -365,7 +369,7 @@
         if (b > 3) pt = 1;
         vlc_coeff = &s->dccv_vlc[pt];
 
-        for (coeff_idx=0; coeff_idx<64; ) {
+        for (coeff_idx = 0;;) {
             int run = 1;
             if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) {
                 s->nb_null[coeff_idx][pt]--;
@@ -400,6 +404,8 @@
                 }
             }
             coeff_idx+=run;
+            if (coeff_idx >= 64)
+                break;
             cg = FFMIN(vp6_coeff_groups[coeff_idx], 3);
             vlc_coeff = &s->ract_vlc[pt][ct][cg];
         }