diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-02-06 16:09:25 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-02-06 16:25:16 +0100 |
commit | 73562f1f834ef0ec8f5f881be73a135b9348c112 (patch) | |
tree | f1889c88bff43a5bc9d0a3129aa62746a7628cd1 | |
parent | 3138b158dd4bff334263b997664e9c1aeb02127b (diff) | |
parent | 8136f234445862c94d1c081606b2d1e3d44fccf3 (diff) | |
download | ffmpeg-73562f1f834ef0ec8f5f881be73a135b9348c112.tar.gz |
Merge commit '8136f234445862c94d1c081606b2d1e3d44fccf3'
* commit '8136f234445862c94d1c081606b2d1e3d44fccf3':
yop: check for input overreads.
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/yop.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/libavcodec/yop.c b/libavcodec/yop.c index 4d9dab8827..be30fa4064 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; @@ -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,14 +192,14 @@ 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"); @@ -202,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]; @@ -232,7 +240,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); |