summaryrefslogtreecommitdiff
path: root/libavcodec/yop.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-02-06 16:09:25 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-02-06 16:25:16 +0100
commit73562f1f834ef0ec8f5f881be73a135b9348c112 (patch)
treef1889c88bff43a5bc9d0a3129aa62746a7628cd1 /libavcodec/yop.c
parent3138b158dd4bff334263b997664e9c1aeb02127b (diff)
parent8136f234445862c94d1c081606b2d1e3d44fccf3 (diff)
Merge commit '8136f234445862c94d1c081606b2d1e3d44fccf3'
* commit '8136f234445862c94d1c081606b2d1e3d44fccf3': yop: check for input overreads. Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/yop.c')
-rw-r--r--libavcodec/yop.c24
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);