diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-04-16 16:44:12 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-04-16 16:44:12 +0200 |
commit | 47f0beadba9003391d8bfef59b15aa21a5b2d293 (patch) | |
tree | 9f95fafb6c43cb4b75f358f0a5d7c10db90c0c49 | |
parent | 71d3c25a7ef442ac2dd7b6fbf7c489ebc0b58e9b (diff) | |
download | ffmpeg-47f0beadba9003391d8bfef59b15aa21a5b2d293.tar.gz |
dsicinav: Check for overread in RLE decode.
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/dsicinav.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 6d18f9a9d9..cd36564eb9 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -179,24 +179,29 @@ static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char return 0; } -static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) { int len, code; unsigned char *dst_end = dst + dst_size; const unsigned char *src_end = src + src_size; - while (src < src_end && dst < dst_end) { + while (src + 1 < src_end && dst < dst_end) { code = *src++; if (code & 0x80) { len = code - 0x7F; memset(dst, *src++, FFMIN(len, dst_end - dst)); } else { len = code + 1; + if (len > src_end-src) { + av_log(0, AV_LOG_ERROR, "RLE overread\n"); + return AVERROR_INVALIDDATA; + } memcpy(dst, src, FFMIN(len, dst_end - dst)); src += len; } dst += len; } + return 0; } static int cinvideo_decode_frame(AVCodecContext *avctx, |