summaryrefslogtreecommitdiff
path: root/libavcodec/flashsv.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-12-19 16:17:21 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-12-19 16:28:26 +0100
commita33c7dd21362a694692d0dc30fdbffae5a5d837e (patch)
treeaa0c785de52a8399e7ba43c82f2783b272239224 /libavcodec/flashsv.c
parentd943330dc01f4d222dc1127d6216cd683dc41ee0 (diff)
downloadffmpeg-a33c7dd21362a694692d0dc30fdbffae5a5d837e.tar.gz
avcodec/flashsv: check decode_hybrid() for overread
Fixes use of uninitialized memory Fixes: msan_uninit-mem_7f906558274e_268_14_244486_2009_04_28.flv Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/flashsv.c')
-rw-r--r--libavcodec/flashsv.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 981d774407..8791a2d750 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -69,7 +69,7 @@ typedef struct FlashSVContext {
int diff_start, diff_height;
} FlashSVContext;
-static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
+static int decode_hybrid(const uint8_t *sptr, const uint8_t *sptr_end, uint8_t *dptr, int dx, int dy,
int h, int w, int stride, const uint32_t *pal)
{
int x, y;
@@ -78,6 +78,8 @@ static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
for (y = dx + h; y > dx; y--) {
uint8_t *dst = dptr + (y * stride) + dy * 3;
for (x = 0; x < w; x++) {
+ if (sptr >= sptr_end)
+ return AVERROR_INVALIDDATA;
if (*sptr & 0x80) {
/* 15-bit color */
unsigned c = AV_RB16(sptr) & ~0x8000;
@@ -232,10 +234,15 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
}
} else {
/* hybrid 15-bit/palette mode */
- decode_hybrid(s->tmpblock, s->frame->data[0],
+ ret = decode_hybrid(s->tmpblock, s->zstream.next_out,
+ s->frame->data[0],
s->image_height - (y_pos + 1 + s->diff_height),
x_pos, s->diff_height, width,
s->frame->linesize[0], s->pal);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "decode_hybrid failed\n");
+ return ret;
+ }
}
skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
return 0;