aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-12-15 04:42:13 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-12-15 04:42:13 +0100
commit30b996d443aeb105d0017b06ce590c55a0b2f9f4 (patch)
treebb3cf8c856098684f9528213e7a5047d26fdd793 /libavcodec
parentafb2bac48d0d044718c2da3d34a97bee244be2e3 (diff)
downloadffmpeg-30b996d443aeb105d0017b06ce590c55a0b2f9f4.tar.gz
flicvideo: input buffer pointer checks.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/flicvideo.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 28009cddba..dded6f5293 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -499,16 +499,27 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
stream_ptr += 6; /* skip the magic number */
num_chunks = AV_RL16(&buf[stream_ptr]);
stream_ptr += 10; /* skip padding */
+ if (frame_size > buf_size)
+ frame_size = buf_size;
frame_size -= 16;
/* iterate through the chunks */
while ((frame_size > 0) && (num_chunks > 0)) {
+ int stream_ptr_after_chunk;
chunk_size = AV_RL32(&buf[stream_ptr]);
+ if (chunk_size > frame_size) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
+ chunk_size = frame_size;
+ }
+ stream_ptr_after_chunk = stream_ptr + chunk_size;
+
stream_ptr += 4;
chunk_type = AV_RL16(&buf[stream_ptr]);
stream_ptr += 2;
+
switch (chunk_type) {
case FLI_256_COLOR:
case FLI_COLOR:
@@ -525,6 +536,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
compressed_lines = AV_RL16(&buf[stream_ptr]);
stream_ptr += 2;
while (compressed_lines > 0) {
+ if (stream_ptr + 2 > stream_ptr_after_chunk)
+ break;
line_packets = AV_RL16(&buf[stream_ptr]);
stream_ptr += 2;
if (line_packets < 0) {
@@ -537,6 +550,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
pixel_countdown = s->avctx->width;
for (i = 0; i < line_packets; i++) {
/* account for the skip bytes */
+ if (stream_ptr + 2 > stream_ptr_after_chunk)
+ break;
pixel_skip = buf[stream_ptr++];
pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
pixel_countdown -= pixel_skip;
@@ -551,6 +566,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
pixel_ptr += 2;
}
} else {
+ if (stream_ptr + 2*byte_run > stream_ptr_after_chunk)
+ break;
CHECK_PIXEL_PTR(2 * byte_run);
for (j = 0; j < byte_run; j++, pixel_countdown--) {
*((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
@@ -586,6 +603,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
pixel_countdown = (s->avctx->width * 2);
while (pixel_countdown > 0) {
+ if (stream_ptr + 1 > stream_ptr_after_chunk)
+ break;
byte_run = (signed char)(buf[stream_ptr++]);
if (byte_run > 0) {
palette_idx1 = buf[stream_ptr++];
@@ -599,6 +618,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
}
} else { /* copy bytes if byte_run < 0 */
byte_run = -byte_run;
+ if (stream_ptr + byte_run > stream_ptr_after_chunk)
+ break;
CHECK_PIXEL_PTR(byte_run);
for (j = 0; j < byte_run; j++) {
palette_idx1 = buf[stream_ptr++];
@@ -638,6 +659,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
while (pixel_countdown > 0) {
+ if (stream_ptr + 1 > stream_ptr_after_chunk)
+ break;
byte_run = (signed char)(buf[stream_ptr++]);
if (byte_run > 0) {
pixel = AV_RL16(&buf[stream_ptr]);
@@ -653,6 +676,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
}
} else { /* copy pixels if byte_run < 0 */
byte_run = -byte_run;
+ if (stream_ptr + 2 * byte_run > stream_ptr_after_chunk)
+ break;
CHECK_PIXEL_PTR(2 * byte_run);
for (j = 0; j < byte_run; j++) {
*((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);