From 8136f234445862c94d1c081606b2d1e3d44fccf3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 30 Jan 2013 07:15:04 +0100 Subject: [PATCH] yop: check for input overreads. CC:libav-stable@libav.org --- libavcodec/yop.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/libavcodec/yop.c b/libavcodec/yop.c index be996c2bfb..3959ada251 100644 --- a/libavcodec/yop.c +++ b/libavcodec/yop.c @@ -39,6 +39,7 @@ typedef struct YopDecContext { uint8_t *low_nibble; uint8_t *srcptr; + uint8_t *src_end; uint8_t *dstptr; uint8_t *dstbuf; } YopDecContext; @@ -123,8 +124,13 @@ static av_cold int yop_decode_close(AVCodecContext *avctx) * @param s codec context * @param tag the tag that was in the nibble */ -static void yop_paint_block(YopDecContext *s, int tag) +static int yop_paint_block(YopDecContext *s, int tag) { + if (s->src_end - s->srcptr < paint_lut[tag][3]) { + av_log(s->avctx, AV_LOG_ERROR, "Packet too small.\n"); + return AVERROR_INVALIDDATA; + } + s->dstptr[0] = s->srcptr[0]; s->dstptr[1] = s->srcptr[paint_lut[tag][0]]; s->dstptr[s->frame.linesize[0]] = s->srcptr[paint_lut[tag][1]]; @@ -132,6 +138,7 @@ static void yop_paint_block(YopDecContext *s, int tag) // The number of src bytes consumed is in the last part of the lut entry. s->srcptr += paint_lut[tag][3]; + return 0; } /** @@ -185,6 +192,11 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int ret, i, x, y; uint32_t *palette; + if (avpkt->size < 4 + 3 * s->num_pal_colors) { + av_log(avctx, AV_LOG_ERROR, "Packet too small.\n"); + return AVERROR_INVALIDDATA; + } + if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); @@ -197,6 +209,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->dstbuf = s->frame.data[0]; s->dstptr = s->frame.data[0]; s->srcptr = avpkt->data + 4; + s->src_end = avpkt->data + avpkt->size; s->low_nibble = NULL; is_odd_frame = avpkt->data[0]; @@ -220,7 +233,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, tag = yop_get_next_nibble(s); if (tag != 0xf) { - yop_paint_block(s, tag); + ret = yop_paint_block(s, tag); + if (ret < 0) + return ret; } else { tag = yop_get_next_nibble(s); ret = yop_copy_previous_block(s, tag);