diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2021-11-13 18:57:59 +0100 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2021-11-29 17:15:07 +0100 |
commit | 2877ddddda04d5c04beaf4482acfa3151c343313 (patch) | |
tree | 25363836875491d80eb2b388b662ca54fa8198f5 | |
parent | 86a2123a6ea69f3f6d1e30c7cb35478ab3620a0d (diff) | |
download | ffmpeg-2877ddddda04d5c04beaf4482acfa3151c343313.tar.gz |
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@niedermayer.cc>
-rw-r--r-- | libavcodec/vqavideo.c | 15 |
1 files 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; |