X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fyop.c;h=234868abbfd41f6e2396a532189f13d131f741fd;hb=bb29ee62e9ef30c26988f386e7c3be7affe836f9;hp=c47f5ec14fc53d79173a7629560db995c54911a0;hpb=d1bbd304bf608c9ca5fe747a8ee317e4c4e0ecbe;p=ffmpeg diff --git a/libavcodec/yop.c b/libavcodec/yop.c index c47f5ec14fc..234868abbfd 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; @@ -89,8 +90,8 @@ static av_cold int yop_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - if (!avctx->extradata) { - av_log(avctx, AV_LOG_ERROR, "extradata missing\n"); + if (avctx->extradata_size < 3) { + av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata.\n"); return AVERROR_INVALIDDATA; } @@ -124,8 +125,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]]; @@ -133,6 +139,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,23 +192,27 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int ret, i, x, y; uint32_t *palette; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - if (avpkt->size < 4 + 3*s->num_pal_colors) { - av_log(avctx, AV_LOG_ERROR, "packet of size %d too small\n", avpkt->size); + 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); + ret = ff_get_buffer(avctx, &s->frame); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } + if (!avctx->frame_number) + memset(s->frame.data[1], 0, AVPALETTE_SIZE); + 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]; @@ -232,7 +243,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);