From 8099187e897ddc90cb3902332c76fb2542dac308 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Thu, 3 May 2012 20:10:36 +0200 Subject: dfa: add some checks to ensure that decoder won't write past frame end --- libavcodec/dfa.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'libavcodec/dfa.c') diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c index 788e9ca90a..4fe6519a93 100644 --- a/libavcodec/dfa.c +++ b/libavcodec/dfa.c @@ -164,6 +164,8 @@ static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height } else if (bitbuf & (mask << 1)) { frame += bytestream2_get_le16(gb) * 2; } else { + if (frame_end - frame < width + 2) + return AVERROR_INVALIDDATA; frame[0] = frame[1] = frame[width] = frame[width + 1] = bytestream2_get_byte(gb); frame += 2; @@ -224,6 +226,7 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height const uint8_t *frame_end = frame + width * height; uint8_t *line_ptr; int count, i, v, lines, segments; + int y = 0; lines = bytestream2_get_le16(gb); if (lines > height) @@ -234,10 +237,12 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height return -1; segments = bytestream2_get_le16u(gb); while ((segments & 0xC000) == 0xC000) { + unsigned skip_lines = -(int16_t)segments; unsigned delta = -((int16_t)segments * width); - if (frame_end - frame <= delta) + if (frame_end - frame <= delta || y + lines + skip_lines > height) return -1; frame += delta; + y += skip_lines; segments = bytestream2_get_le16(gb); } if (segments & 0x8000) { @@ -246,6 +251,7 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height } line_ptr = frame; frame += width; + y++; while (segments--) { if (frame - line_ptr <= bytestream2_peek_byte(gb)) return -1; -- cgit v1.2.3