They seem all reachable from bogus input.
---
 libavcodec/ffv1dec.c | 83 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 52 insertions(+), 31 deletions(-)

diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 8f7b2bf..2ff1f8c 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -25,7 +25,6 @@
  * FF Video Codec 1 (a lossless codec) decoder
  */
 
-#include "libavutil/avassert.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/crc.h"
 #include "libavutil/opt.h"
@@ -77,7 +76,8 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState 
*const state,
         i += i;
     }
 
-    assert(k <= 8);
+    if (k > 8)
+        return AVERROR_INVALIDDATA;
 
     v = get_sr_golomb(gb, k, 12, bits);
     av_dlog(NULL, "v:%d bias:%d error:%d drift:%d count:%d k:%d",
@@ -97,9 +97,9 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState 
*const state,
     return ret;
 }
 
-static av_always_inline void decode_line(FFV1Context *s, int w,
-                                         int16_t *sample[2],
-                                         int plane_index, int bits)
+static av_always_inline int decode_line(FFV1Context *s, int w,
+                                        int16_t *sample[2],
+                                        int plane_index, int bits)
 {
     PlaneContext *const p = &s->plane[plane_index];
     RangeCoder *const c   = &s->c;
@@ -118,7 +118,8 @@ static av_always_inline void decode_line(FFV1Context *s, 
int w,
         } else
             sign = 0;
 
-        av_assert2(context < p->context_count);
+        if (context >= p->context_count)
+            return AVERROR_INVALIDDATA;
 
         if (s->ac) {
             diff = get_symbol_inline(c, p->state[context], 1);
@@ -166,12 +167,13 @@ static av_always_inline void decode_line(FFV1Context *s, 
int w,
                        ((1 << bits) - 1);
     }
     s->run_index = run_index;
+    return 0;
 }
 
-static void decode_plane(FFV1Context *s, uint8_t *src,
+static int decode_plane(FFV1Context *s, uint8_t *src,
                          int w, int h, int stride, int plane_index)
 {
-    int x, y;
+    int x, y, ret;
     int16_t *sample[2];
     sample[0] = s->sample_buffer + 3;
     sample[1] = s->sample_buffer + w + 6 + 3;
@@ -191,12 +193,16 @@ static void decode_plane(FFV1Context *s, uint8_t *src,
 
 // { START_TIMER
         if (s->avctx->bits_per_raw_sample <= 8) {
-            decode_line(s, w, sample, plane_index, 8);
+            ret = decode_line(s, w, sample, plane_index, 8);
+            if (ret < 0)
+                return ret;
             for (x = 0; x < w; x++)
                 src[x + stride * y] = sample[1][x];
         } else {
-            decode_line(s, w, sample, plane_index,
-                        s->avctx->bits_per_raw_sample);
+            ret = decode_line(s, w, sample, plane_index,
+                              s->avctx->bits_per_raw_sample);
+            if (ret < 0)
+                return ret;
             if (s->packed_at_lsb) {
                 for (x = 0; x < w; x++)
                     ((uint16_t *)(src + stride * y))[x] = sample[1][x];
@@ -207,12 +213,13 @@ static void decode_plane(FFV1Context *s, uint8_t *src,
         }
 // STOP_TIMER("decode-line") }
     }
+    return 0;
 }
 
-static void decode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h,
-                             int stride[3])
+static int decode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h,
+                            int stride[3])
 {
-    int x, y, p;
+    int x, y, p, ret;
     int16_t *sample[4][2];
     int lbd  = s->avctx->bits_per_raw_sample <= 8;
     int bits = s->avctx->bits_per_raw_sample > 0
@@ -239,9 +246,12 @@ static void decode_rgb_frame(FFV1Context *s, uint8_t 
*src[3], int w, int h,
             sample[p][1][-1] = sample[p][0][0];
             sample[p][0][w]  = sample[p][0][w - 1];
             if (lbd)
-                decode_line(s, w, sample[p], (p + 1) / 2, 9);
+                ret = decode_line(s, w, sample[p], (p + 1) / 2, 9);
             else
-                decode_line(s, w, sample[p], (p + 1) / 2, bits + 1);
+                ret = decode_line(s, w, sample[p], (p + 1) / 2, bits + 1);
+
+            if (ret < 0)
+                return ret;
         }
         for (x = 0; x < w; x++) {
             int g = sample[0][1][x];
@@ -265,6 +275,7 @@ static void decode_rgb_frame(FFV1Context *s, uint8_t 
*src[3], int w, int h,
             }
         }
     }
+    return 0;
 }
 
 static int decode_slice_header(FFV1Context *f, FFV1Context *fs)
@@ -290,6 +301,9 @@ static int decode_slice_header(FFV1Context *f, FFV1Context 
*fs)
     fs->slice_y     /= f->num_v_slices;
     fs->slice_width  = fs->slice_width / f->num_h_slices - fs->slice_x;
     fs->slice_height = fs->slice_height / f->num_v_slices - fs->slice_y;
+
+    if (fs->slice_width <= 0 || fs->slice_height <= 0)
+        return AVERROR_INVALIDDATA;
     if ((unsigned)fs->slice_width  > f->width ||
         (unsigned)fs->slice_height > f->height)
         return AVERROR_INVALIDDATA;
@@ -365,33 +379,39 @@ static int decode_slice(AVCodecContext *c, void *arg)
                        fs->ac_byte_count) * 8);
     }
 
-    av_assert1(width && height);
     if (f->colorspace == 0) {
         const int chroma_width  = -((-width) >> f->chroma_h_shift);
         const int chroma_height = -((-height) >> f->chroma_v_shift);
         const int cx            = x >> f->chroma_h_shift;
         const int cy            = y >> f->chroma_v_shift;
-        decode_plane(fs, p->data[0] + ps * x + y * p->linesize[0], width,
-                     height, p->linesize[0],
-                     0);
+
+        ret = decode_plane(fs, p->data[0] + ps * x + y * p->linesize[0],
+                           width, height, p->linesize[0], 0);
+        if (ret < 0)
+            return ret;
 
         if (f->chroma_planes) {
-            decode_plane(fs, p->data[1] + ps * cx + cy * p->linesize[1],
-                         chroma_width, chroma_height, p->linesize[1],
-                         1);
-            decode_plane(fs, p->data[2] + ps * cx + cy * p->linesize[2],
-                         chroma_width, chroma_height, p->linesize[2],
-                         1);
+            ret = decode_plane(fs, p->data[1] + ps * cx + cy * p->linesize[1],
+                               chroma_width, chroma_height, p->linesize[1], 1);
+            if (ret < 0)
+                return ret;
+            ret = decode_plane(fs, p->data[2] + ps * cx + cy * p->linesize[2],
+                               chroma_width, chroma_height, p->linesize[2], 1);
+            if (ret < 0)
+                return ret;
         }
         if (fs->transparency)
-            decode_plane(fs, p->data[3] + ps * x + y * p->linesize[3], width,
-                         height, p->linesize[3],
-                         2);
+            ret = decode_plane(fs, p->data[3] + ps * x + y * p->linesize[3],
+                               width, height, p->linesize[3], 2);
+            if (ret < 0)
+                return ret;
     } else {
         uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0],
                                p->data[1] + ps * x + y * p->linesize[1],
                                p->data[2] + ps * x + y * p->linesize[2] };
-        decode_rgb_frame(fs, planes, width, height, p->linesize);
+        ret = decode_rgb_frame(fs, planes, width, height, p->linesize);
+        if (ret < 0)
+            return ret;
     }
     if (fs->ac && f->version > 2) {
         int v;
@@ -766,7 +786,8 @@ static int read_header(FFV1Context *f)
             }
 
             if (f->version <= 2) {
-                av_assert0(context_count >= 0);
+                if (context_count < 0)
+                    return AVERROR_INVALIDDATA;
                 if (p->context_count < context_count) {
                     av_freep(&p->state);
                     av_freep(&p->vlc_state);
-- 
1.8.5.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to