aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2006-09-07 04:05:04 +0000
committerKostya Shishkov <kostya.shishkov@gmail.com>2006-09-07 04:05:04 +0000
commit096bc417ae9b5bf35631d48fbc798020aac08aee (patch)
tree89c2cc5b78163f1ee6231a30e5df468e911fb2f4
parent54b55c8da0afc923129163e1d5ab0ec1fcbffd86 (diff)
downloadffmpeg-096bc417ae9b5bf35631d48fbc798020aac08aee.tar.gz
Tests for overreading input data
Originally committed as revision 6184 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/vmnc.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index ac50221c2e..496f39dba9 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -223,7 +223,7 @@ static always_inline void paint_raw(uint8_t *dst, int w, int h, uint8_t* src, in
}
}
-static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int w, int h, int stride)
+static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int ssize, int w, int h, int stride)
{
int i, j, k;
int bg = 0, fg = 0, rects, color, flags, xy, wh;
@@ -237,9 +237,17 @@ static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int w, int
bw = 16;
if(j + 16 > h) bh = h - j;
for(i = 0; i < w; i += 16, dst2 += 16 * bpp) {
+ if(src - ssrc >= ssize) {
+ av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
+ return -1;
+ }
if(i + 16 > w) bw = w - i;
flags = *src++;
if(flags & HT_RAW) {
+ if(src - ssrc > ssize - bw * bh * bpp) {
+ av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
+ return -1;
+ }
paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride);
src += bw * bh * bpp;
} else {
@@ -252,10 +260,14 @@ static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int w, int
rects = 0;
if(flags & HT_SUB)
rects = *src++;
- color = (flags & HT_CLR);
+ color = !!(flags & HT_CLR);
paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);
+ if(src - ssrc > ssize - rects * (color * bpp + 2)) {
+ av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
+ return -1;
+ }
for(k = 0; k < rects; k++) {
if(color) {
fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
@@ -276,7 +288,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
VmncContext * const c = (VmncContext *)avctx->priv_data;
uint8_t *outptr;
uint8_t *src = buf;
- int dx, dy, w, h, depth, enc, chunks, res;
+ int dx, dy, w, h, depth, enc, chunks, res, size_left;
c->pic.reference = 1;
c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
@@ -322,8 +334,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
h = BE_16(src); src += 2;
enc = BE_32(src); src += 4;
outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
+ size_left = buf_size - (src - buf);
switch(enc) {
case MAGIC_WMVd: // cursor
+ if(size_left < 2 + w * h * c->bpp2 * 2) {
+ av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left);
+ return -1;
+ }
src += 2;
c->cur_w = w;
c->cur_h = h;
@@ -367,6 +384,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
return -1;
}
+ if(size_left < w * h * c->bpp2) {
+ av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left);
+ return -1;
+ }
paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]);
src += w * h * c->bpp2;
break;
@@ -375,7 +396,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
return -1;
}
- res = decode_hextile(c, outptr, src, w, h, c->pic.linesize[0]);
+ res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]);
if(res < 0)
return -1;
src += res;