summaryrefslogtreecommitdiff
path: root/libavcodec/dsicinav.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-04-16 16:44:12 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-04-16 16:44:12 +0200
commit47f0beadba9003391d8bfef59b15aa21a5b2d293 (patch)
tree9f95fafb6c43cb4b75f358f0a5d7c10db90c0c49 /libavcodec/dsicinav.c
parent71d3c25a7ef442ac2dd7b6fbf7c489ebc0b58e9b (diff)
dsicinav: Check for overread in RLE decode.
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/dsicinav.c')
-rw-r--r--libavcodec/dsicinav.c9
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,