[FFmpeg-cvslog] avcodec/vqavideo: Use GetByteContext and check for end

Michael Niedermayer git at videolan.org
Mon Nov 29 19:42:21 EET 2021


ffmpeg | branch: master | Michael Niedermayer <michael at niedermayer.cc> | Sat Nov 13 18:57:59 2021 +0100| [2877ddddda04d5c04beaf4482acfa3151c343313] | committer: Michael Niedermayer

avcodec/vqavideo: Use GetByteContext and check for end

Fixes: out of array access
Fixes: Timeout
Fixes: 40481/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_VQA_fuzzer-6502647583080448

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

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

 libavcodec/vqavideo.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index 61f0a2c950..7c1d42bcac 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -633,7 +633,7 @@ static int vqa_decode_frame_hicolor(VqaContext *s, AVFrame *frame)
     int vptr_chunk = -1;
     int vprz_chunk = -1;
 
-    const unsigned char *stream;
+    GetByteContext gb_stream;
 
     while (bytestream2_get_bytes_left(&s->gb) >= 8) {
         chunk_type = bytestream2_get_be32u(&s->gb);
@@ -717,7 +717,7 @@ static int vqa_decode_frame_hicolor(VqaContext *s, AVFrame *frame)
 
     /* now uncompress the per-row RLE of the decode buffer and draw the blocks in framebuffer */
 
-    stream = (unsigned char*)s->decode_buffer;
+    bytestream2_init(&gb_stream, s->decode_buffer, s->decode_buffer_size);
 
     for (int y_pos = 0; y_pos < s->height; y_pos += s->vector_height) {
         int x_pos = 0;
@@ -725,9 +725,14 @@ static int vqa_decode_frame_hicolor(VqaContext *s, AVFrame *frame)
         while (x_pos < s->width) {
             int vector_index = 0;
             int count = 0;
-            uint16_t code = bytestream_get_le16(&stream);
+            uint16_t code;
             int type;
 
+            if (bytestream2_get_bytes_left(&gb_stream) < 2)
+                return AVERROR_INVALIDDATA;
+
+            code = bytestream2_get_le16(&gb_stream);
+
             type = code >> 13;
             code &= 0x1fff;
 
@@ -742,7 +747,7 @@ static int vqa_decode_frame_hicolor(VqaContext *s, AVFrame *frame)
                 count = 1;
             } else if (type < 7) {
                 vector_index = code;
-                count = *stream++;
+                count = bytestream2_get_byte(&gb_stream);
             } else {
                 av_log(s->avctx, AV_LOG_ERROR, " unknown type in VPTR chunk (%d)\n",type);
                 return AVERROR_INVALIDDATA;
@@ -771,7 +776,7 @@ static int vqa_decode_frame_hicolor(VqaContext *s, AVFrame *frame)
 
                 /* we might want to read the next block index from stream */
                 if ((type == 2) && count > 0) {
-                    vector_index = bytestream_get_byte(&stream);
+                    vector_index = bytestream2_get_byte(&gb_stream);
                 }
 
                 x_pos += 4;



More information about the ffmpeg-cvslog mailing list