Check for out of bound reads in vmd_decode() of vmd video decoder.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit e07377e736)
This commit is contained in:
Laurent Aimar 2011-09-25 00:08:49 +02:00 committed by Michael Niedermayer
parent 08657a2a8a
commit 55efeba2b5
1 changed files with 19 additions and 4 deletions

View File

@ -203,6 +203,7 @@ static void vmd_decode(VmdVideoContext *s)
const unsigned char *p_end = s->buf + s->size;
const unsigned char *pb;
const unsigned char *pb_end;
unsigned char meth;
unsigned char *dp; /* pointer to current frame */
unsigned char *pp; /* pointer to previous frame */
@ -248,6 +249,8 @@ static void vmd_decode(VmdVideoContext *s)
/* check if there is a new palette */
if (s->buf[15] & 0x02) {
if (p_end - p < 2 + 3 * PALETTE_COUNT)
return;
p += 2;
palette32 = (unsigned int *)s->palette;
for (i = 0; i < PALETTE_COUNT; i++) {
@ -256,16 +259,17 @@ static void vmd_decode(VmdVideoContext *s)
b = *p++ * 4;
palette32[i] = (r << 16) | (g << 8) | (b);
}
s->size -= (256 * 3 + 2);
}
if (s->size >= 0) {
if (p < p_end) {
/* originally UnpackFrame in VAG's code */
pb = p;
pb_end = p_end;
meth = *pb++;
if (meth & 0x80) {
lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
meth &= 0x7F;
pb = s->unpack_buffer;
pb_end = s->unpack_buffer + s->unpack_buffer_size;
}
dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
@ -275,10 +279,12 @@ static void vmd_decode(VmdVideoContext *s)
for (i = 0; i < frame_height; i++) {
ofs = 0;
do {
if (pb_end - pb < 1)
return;
len = *pb++;
if (len & 0x80) {
len = (len & 0x7F) + 1;
if (ofs + len > frame_width)
if (ofs + len > frame_width || pb_end - pb < len)
return;
memcpy(&dp[ofs], pb, len);
pb += len;
@ -303,6 +309,8 @@ static void vmd_decode(VmdVideoContext *s)
case 2:
for (i = 0; i < frame_height; i++) {
if (pb_end -pb < frame_width)
return;
memcpy(dp, pb, frame_width);
pb += frame_width;
dp += s->frame.linesize[0];
@ -314,13 +322,20 @@ static void vmd_decode(VmdVideoContext *s)
for (i = 0; i < frame_height; i++) {
ofs = 0;
do {
if (pb_end - pb < 1)
return;
len = *pb++;
if (len & 0x80) {
len = (len & 0x7F) + 1;
if (pb_end - pb < 1)
return;
if (*pb++ == 0xFF)
len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
else
else {
if (pb_end - pb < len)
return;
memcpy(&dp[ofs], pb, len);
}
pb += len;
ofs += len;
} else {