[FFmpeg-cvslog] dfa: add some checks to ensure that decoder won't write past frame end

Kostya Shishkov git at videolan.org
Mon Feb 18 01:09:43 CET 2013


ffmpeg | branch: release/0.7 | Kostya Shishkov <kostya.shishkov at gmail.com> | Thu May  3 20:10:36 2012 +0200| [2d63f9b4effc062138537190d4b9201d5e51cb8d] | committer: Reinhard Tartler

dfa: add some checks to ensure that decoder won't write past frame end

(cherry picked from commit 8099187e897ddc90cb3902332c76fb2542dac308)

Signed-off-by: Reinhard Tartler <siretart at tauware.de>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2d63f9b4effc062138537190d4b9201d5e51cb8d
---

 libavcodec/dfa.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 1cb97dc..eeb96cf 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -176,6 +176,8 @@ static int decode_dds1(uint8_t *frame, int width, int height,
         } else if (bitbuf & (mask << 1)) {
             frame += bytestream_get_le16(&src) * 2;
         } else {
+            if (frame_end - frame < width + 2)
+                return AVERROR_INVALIDDATA;
             frame[0] = frame[1] =
             frame[width] = frame[width + 1] =  *src++;
             frame += 2;
@@ -237,6 +239,7 @@ static int decode_wdlt(uint8_t *frame, int width, int height,
     const uint8_t *frame_end   = frame + width * height;
     uint8_t *line_ptr;
     int count, i, v, lines, segments;
+    int y = 0;
 
     lines = bytestream_get_le16(&src);
     if (lines > height || src >= src_end)
@@ -245,10 +248,12 @@ static int decode_wdlt(uint8_t *frame, int width, int height,
     while (lines--) {
         segments = bytestream_get_le16(&src);
         while ((segments & 0xC000) == 0xC000) {
+            unsigned skip_lines = -(int16_t)segments;
             unsigned delta = -((int16_t)segments * width);
-            if (frame_end - frame <= delta)
+            if (frame_end - frame <= delta || y + lines + skip_lines > height)
                 return -1;
             frame    += delta;
+            y        += skip_lines;
             segments = bytestream_get_le16(&src);
         }
         if (segments & 0x8000) {
@@ -257,6 +262,7 @@ static int decode_wdlt(uint8_t *frame, int width, int height,
         }
         line_ptr = frame;
         frame += width;
+        y++;
         while (segments--) {
             if (src_end - src < 2)
                 return -1;



More information about the ffmpeg-cvslog mailing list