yop: check for input overreads.

CC:libav-stable@libav.org
pull/9/head
Anton Khirnov 12 years ago
parent 06cf597c35
commit 8136f23444
  1. 19
      libavcodec/yop.c

@ -39,6 +39,7 @@ typedef struct YopDecContext {
uint8_t *low_nibble; uint8_t *low_nibble;
uint8_t *srcptr; uint8_t *srcptr;
uint8_t *src_end;
uint8_t *dstptr; uint8_t *dstptr;
uint8_t *dstbuf; uint8_t *dstbuf;
} YopDecContext; } YopDecContext;
@ -123,8 +124,13 @@ static av_cold int yop_decode_close(AVCodecContext *avctx)
* @param s codec context * @param s codec context
* @param tag the tag that was in the nibble * @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[0] = s->srcptr[0];
s->dstptr[1] = s->srcptr[paint_lut[tag][0]]; s->dstptr[1] = s->srcptr[paint_lut[tag][0]];
s->dstptr[s->frame.linesize[0]] = s->srcptr[paint_lut[tag][1]]; 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. // The number of src bytes consumed is in the last part of the lut entry.
s->srcptr += paint_lut[tag][3]; 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; int ret, i, x, y;
uint32_t *palette; 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]) if (s->frame.data[0])
avctx->release_buffer(avctx, &s->frame); 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->dstbuf = s->frame.data[0];
s->dstptr = s->frame.data[0]; s->dstptr = s->frame.data[0];
s->srcptr = avpkt->data + 4; s->srcptr = avpkt->data + 4;
s->src_end = avpkt->data + avpkt->size;
s->low_nibble = NULL; s->low_nibble = NULL;
is_odd_frame = avpkt->data[0]; 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); tag = yop_get_next_nibble(s);
if (tag != 0xf) { if (tag != 0xf) {
yop_paint_block(s, tag); ret = yop_paint_block(s, tag);
if (ret < 0)
return ret;
} else { } else {
tag = yop_get_next_nibble(s); tag = yop_get_next_nibble(s);
ret = yop_copy_previous_block(s, tag); ret = yop_copy_previous_block(s, tag);

Loading…
Cancel
Save