Commit e07377e7 authored by Laurent Aimar's avatar Laurent Aimar Committed by Michael Niedermayer

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

Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 3b26daed
...@@ -203,6 +203,7 @@ static void vmd_decode(VmdVideoContext *s) ...@@ -203,6 +203,7 @@ static void vmd_decode(VmdVideoContext *s)
const unsigned char *p_end = s->buf + s->size; const unsigned char *p_end = s->buf + s->size;
const unsigned char *pb; const unsigned char *pb;
const unsigned char *pb_end;
unsigned char meth; unsigned char meth;
unsigned char *dp; /* pointer to current frame */ unsigned char *dp; /* pointer to current frame */
unsigned char *pp; /* pointer to previous frame */ unsigned char *pp; /* pointer to previous frame */
...@@ -248,6 +249,8 @@ static void vmd_decode(VmdVideoContext *s) ...@@ -248,6 +249,8 @@ static void vmd_decode(VmdVideoContext *s)
/* check if there is a new palette */ /* check if there is a new palette */
if (s->buf[15] & 0x02) { if (s->buf[15] & 0x02) {
if (p_end - p < 2 + 3 * PALETTE_COUNT)
return;
p += 2; p += 2;
palette32 = (unsigned int *)s->palette; palette32 = (unsigned int *)s->palette;
for (i = 0; i < PALETTE_COUNT; i++) { for (i = 0; i < PALETTE_COUNT; i++) {
...@@ -256,16 +259,17 @@ static void vmd_decode(VmdVideoContext *s) ...@@ -256,16 +259,17 @@ static void vmd_decode(VmdVideoContext *s)
b = *p++ * 4; b = *p++ * 4;
palette32[i] = (r << 16) | (g << 8) | (b); 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 */ /* originally UnpackFrame in VAG's code */
pb = p; pb = p;
pb_end = p_end;
meth = *pb++; meth = *pb++;
if (meth & 0x80) { if (meth & 0x80) {
lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size); lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
meth &= 0x7F; meth &= 0x7F;
pb = s->unpack_buffer; 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]; dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
...@@ -275,10 +279,12 @@ static void vmd_decode(VmdVideoContext *s) ...@@ -275,10 +279,12 @@ static void vmd_decode(VmdVideoContext *s)
for (i = 0; i < frame_height; i++) { for (i = 0; i < frame_height; i++) {
ofs = 0; ofs = 0;
do { do {
if (pb_end - pb < 1)
return;
len = *pb++; len = *pb++;
if (len & 0x80) { if (len & 0x80) {
len = (len & 0x7F) + 1; len = (len & 0x7F) + 1;
if (ofs + len > frame_width) if (ofs + len > frame_width || pb_end - pb < len)
return; return;
memcpy(&dp[ofs], pb, len); memcpy(&dp[ofs], pb, len);
pb += len; pb += len;
...@@ -303,6 +309,8 @@ static void vmd_decode(VmdVideoContext *s) ...@@ -303,6 +309,8 @@ static void vmd_decode(VmdVideoContext *s)
case 2: case 2:
for (i = 0; i < frame_height; i++) { for (i = 0; i < frame_height; i++) {
if (pb_end -pb < frame_width)
return;
memcpy(dp, pb, frame_width); memcpy(dp, pb, frame_width);
pb += frame_width; pb += frame_width;
dp += s->frame.linesize[0]; dp += s->frame.linesize[0];
...@@ -314,13 +322,20 @@ static void vmd_decode(VmdVideoContext *s) ...@@ -314,13 +322,20 @@ static void vmd_decode(VmdVideoContext *s)
for (i = 0; i < frame_height; i++) { for (i = 0; i < frame_height; i++) {
ofs = 0; ofs = 0;
do { do {
if (pb_end - pb < 1)
return;
len = *pb++; len = *pb++;
if (len & 0x80) { if (len & 0x80) {
len = (len & 0x7F) + 1; len = (len & 0x7F) + 1;
if (pb_end - pb < 1)
return;
if (*pb++ == 0xFF) if (*pb++ == 0xFF)
len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs); len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
else else {
if (pb_end - pb < len)
return;
memcpy(&dp[ofs], pb, len); memcpy(&dp[ofs], pb, len);
}
pb += len; pb += len;
ofs += len; ofs += len;
} else { } else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment