[FFmpeg-cvslog] g2meet: more graceful cursor loading

Kostya Shishkov git at videolan.org
Wed Jun 12 12:16:24 CEST 2013


ffmpeg | branch: master | Kostya Shishkov <kostya.shishkov at gmail.com> | Tue Jun 11 19:07:38 2013 +0200| [4d960d7f60f96c24e0a9bb8224c83a7cfa4f26d4] | committer: Kostya Shishkov

g2meet: more graceful cursor loading

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

 libavcodec/g2meet.c |   71 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 53 insertions(+), 18 deletions(-)

diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c
index d0a4302..f7a8501 100644
--- a/libavcodec/g2meet.c
+++ b/libavcodec/g2meet.c
@@ -468,16 +468,63 @@ static int g2m_init_buffers(G2MContext *c)
     return 0;
 }
 
-static int g2m_load_cursor(G2MContext *c, GetByteContext *gb)
+static int g2m_load_cursor(AVCodecContext *avctx, G2MContext *c,
+                           GetByteContext *gb)
 {
     int i, j, k;
     uint8_t *dst;
     uint32_t bits;
+    uint32_t cur_size, cursor_w, cursor_h, cursor_stride;
+    uint32_t cursor_hot_x, cursor_hot_y;
+    int cursor_fmt;
+    uint8_t *tmp;
 
-    c->cursor_stride = c->cursor_w * 4;
-    c->cursor        = av_realloc(c->cursor, c->cursor_stride * c->cursor_h);
-    if (!c->cursor)
+    cur_size      = bytestream2_get_be32(gb);
+    cursor_w      = bytestream2_get_byte(gb);
+    cursor_h      = bytestream2_get_byte(gb);
+    cursor_hot_x  = bytestream2_get_byte(gb);
+    cursor_hot_y  = bytestream2_get_byte(gb);
+    cursor_fmt    = bytestream2_get_byte(gb);
+
+    cursor_stride = cursor_w * 4;
+
+    if (cursor_w < 1 || cursor_w > 256 ||
+        cursor_h < 1 || cursor_h > 256) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid cursor dimensions %dx%d\n",
+               cursor_w, cursor_h);
+        return AVERROR_INVALIDDATA;
+    }
+    if (cursor_hot_x > cursor_w || cursor_hot_y > cursor_h) {
+        av_log(avctx, AV_LOG_WARNING, "Invalid hotspot position %d,%d\n",
+               cursor_hot_x, cursor_hot_y);
+        cursor_hot_x = FFMIN(cursor_hot_x, cursor_w - 1);
+        cursor_hot_y = FFMIN(cursor_hot_y, cursor_h - 1);
+    }
+    if (cur_size - 9 > bytestream2_get_bytes_left(gb) ||
+        c->cursor_w * c->cursor_h / 4 > cur_size) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d/%d\n",
+               cur_size, bytestream2_get_bytes_left(gb));
+        return AVERROR_INVALIDDATA;
+    }
+    if (cursor_fmt != 1 && cursor_fmt != 32) {
+        avpriv_report_missing_feature(avctx, "Cursor format %d",
+                                      cursor_fmt);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    tmp = av_realloc(c->cursor, cursor_stride * cursor_h);
+    if (!tmp) {
+        av_log(avctx, AV_LOG_ERROR, "Cannot allocate cursor buffer\n");
         return AVERROR(ENOMEM);
+    }
+
+    c->cursor        = tmp;
+    c->cursor_w      = cursor_w;
+    c->cursor_h      = cursor_h;
+    c->cursor_hot_x  = cursor_hot_x;
+    c->cursor_hot_y  = cursor_hot_y;
+    c->cursor_fmt    = cursor_fmt;
+    c->cursor_stride = cursor_stride;
 
     dst = c->cursor;
     switch (c->cursor_fmt) {
@@ -597,7 +644,7 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data,
     GetByteContext bc, tbc;
     int magic;
     int got_header = 0;
-    uint32_t chunk_size, cur_size;
+    uint32_t chunk_size;
     int chunk_type;
     int i;
     int ret;
@@ -734,19 +781,7 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data,
             }
             bytestream2_init(&tbc, buf + bytestream2_tell(&bc),
                              chunk_size - 4);
-            cur_size        = bytestream2_get_be32(&tbc);
-            c->cursor_w     = bytestream2_get_byte(&tbc);
-            c->cursor_h     = bytestream2_get_byte(&tbc);
-            c->cursor_hot_x = bytestream2_get_byte(&tbc);
-            c->cursor_hot_y = bytestream2_get_byte(&tbc);
-            c->cursor_fmt   = bytestream2_get_byte(&tbc);
-            if (cur_size >= chunk_size ||
-                c->cursor_w * c->cursor_h / 4 > cur_size) {
-                av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d\n",
-                       chunk_size);
-                break;
-            }
-            g2m_load_cursor(c, &tbc);
+            g2m_load_cursor(avctx, c, &tbc);
             bytestream2_skip(&bc, chunk_size);
             break;
         case CHUNK_CC:



More information about the ffmpeg-cvslog mailing list