1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

Fix out of bound reads in rle_unpack() of vmd video decoder.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Laurent Aimar 2011-09-25 00:08:50 +02:00 committed by Michael Niedermayer
parent e07377e736
commit 4749e07498

View File

@ -153,32 +153,39 @@ static void lz_unpack(const unsigned char *src, int src_len,
} }
} }
static int rle_unpack(const unsigned char *src, unsigned char *dest, static int rle_unpack(const unsigned char *src, int src_len, int src_count,
int src_len, int dest_len) unsigned char *dest, int dest_len)
{ {
const unsigned char *ps; const unsigned char *ps;
const unsigned char *ps_end;
unsigned char *pd; unsigned char *pd;
int i, l; int i, l;
unsigned char *dest_end = dest + dest_len; unsigned char *dest_end = dest + dest_len;
ps = src; ps = src;
ps_end = src + src_len;
pd = dest; pd = dest;
if (src_len & 1) if (src_count & 1) {
if (ps_end - ps < 1)
return 0;
*pd++ = *ps++; *pd++ = *ps++;
}
src_len >>= 1; src_count >>= 1;
i = 0; i = 0;
do { do {
if (ps_end - ps < 1)
break;
l = *ps++; l = *ps++;
if (l & 0x80) { if (l & 0x80) {
l = (l & 0x7F) * 2; l = (l & 0x7F) * 2;
if (pd + l > dest_end) if (pd + l > dest_end || ps_end - ps < l)
return ps - src; return ps - src;
memcpy(pd, ps, l); memcpy(pd, ps, l);
ps += l; ps += l;
pd += l; pd += l;
} else { } else {
if (pd + i > dest_end) if (pd + i > dest_end || ps_end - ps < 2)
return ps - src; return ps - src;
for (i = 0; i < l; i++) { for (i = 0; i < l; i++) {
*pd++ = ps[0]; *pd++ = ps[0];
@ -187,7 +194,7 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
ps += 2; ps += 2;
} }
i += l; i += l;
} while (i < src_len); } while (i < src_count);
return ps - src; return ps - src;
} }
@ -330,7 +337,7 @@ static void vmd_decode(VmdVideoContext *s)
if (pb_end - pb < 1) if (pb_end - pb < 1)
return; return;
if (*pb++ == 0xFF) if (*pb++ == 0xFF)
len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs); len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs);
else { else {
if (pb_end - pb < len) if (pb_end - pb < len)
return; return;