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

Prevent out of bound accesses in the xan decoder.

Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent b9596a50
...@@ -220,6 +220,10 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, ...@@ -220,6 +220,10 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s,
int width = s->avctx->width; int width = s->avctx->width;
unsigned char *palette_plane, *prev_palette_plane; unsigned char *palette_plane, *prev_palette_plane;
if ( y + motion_y < 0 || y + motion_y >= s->avctx->height ||
x + motion_x < 0 || x + motion_x >= s->avctx->width)
return;
palette_plane = s->current_frame.data[0]; palette_plane = s->current_frame.data[0];
prev_palette_plane = s->last_frame.data[0]; prev_palette_plane = s->last_frame.data[0];
if (!prev_palette_plane) if (!prev_palette_plane)
...@@ -230,7 +234,9 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, ...@@ -230,7 +234,9 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s,
curframe_x = x; curframe_x = x;
prevframe_index = (y + motion_y) * stride + x + motion_x; prevframe_index = (y + motion_y) * stride + x + motion_x;
prevframe_x = x + motion_x; prevframe_x = x + motion_x;
while(pixel_count && (curframe_index < s->frame_size)) { while(pixel_count &&
curframe_index < s->frame_size &&
prevframe_index < s->frame_size) {
int count = FFMIN3(pixel_count, width - curframe_x, width - prevframe_x); int count = FFMIN3(pixel_count, width - curframe_x, width - prevframe_x);
memcpy(palette_plane + curframe_index, prev_palette_plane + prevframe_index, count); memcpy(palette_plane + curframe_index, prev_palette_plane + prevframe_index, count);
...@@ -264,6 +270,7 @@ static int xan_wc3_decode_frame(XanContext *s) { ...@@ -264,6 +270,7 @@ static int xan_wc3_decode_frame(XanContext *s) {
int x, y; int x, y;
unsigned char *opcode_buffer = s->buffer1; unsigned char *opcode_buffer = s->buffer1;
unsigned char *opcode_buffer_end = s->buffer1 + s->buffer1_size;
int opcode_buffer_size = s->buffer1_size; int opcode_buffer_size = s->buffer1_size;
const unsigned char *imagedata_buffer = s->buffer2; const unsigned char *imagedata_buffer = s->buffer2;
...@@ -272,7 +279,7 @@ static int xan_wc3_decode_frame(XanContext *s) { ...@@ -272,7 +279,7 @@ static int xan_wc3_decode_frame(XanContext *s) {
const unsigned char *size_segment; const unsigned char *size_segment;
const unsigned char *vector_segment; const unsigned char *vector_segment;
const unsigned char *imagedata_segment; const unsigned char *imagedata_segment;
int huffman_offset, size_offset, vector_offset, imagedata_offset; int huffman_offset, size_offset, vector_offset, imagedata_offset, imagedata_size;
if (s->size < 8) if (s->size < 8)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
...@@ -297,14 +304,17 @@ static int xan_wc3_decode_frame(XanContext *s) { ...@@ -297,14 +304,17 @@ static int xan_wc3_decode_frame(XanContext *s) {
huffman_segment, s->size - huffman_offset) < 0) huffman_segment, s->size - huffman_offset) < 0)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
if (imagedata_segment[0] == 2) if (imagedata_segment[0] == 2) {
xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size); xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size);
else imagedata_size = s->buffer2_size;
} else {
imagedata_size = s->size - imagedata_offset - 1;
imagedata_buffer = &imagedata_segment[1]; imagedata_buffer = &imagedata_segment[1];
}
/* use the decoded data segments to build the frame */ /* use the decoded data segments to build the frame */
x = y = 0; x = y = 0;
while (total_pixels) { while (total_pixels && opcode_buffer < opcode_buffer_end) {
opcode = *opcode_buffer++; opcode = *opcode_buffer++;
size = 0; size = 0;
...@@ -353,6 +363,8 @@ static int xan_wc3_decode_frame(XanContext *s) { ...@@ -353,6 +363,8 @@ static int xan_wc3_decode_frame(XanContext *s) {
size_segment += 3; size_segment += 3;
break; break;
} }
if (size > total_pixels)
break;
if (opcode < 12) { if (opcode < 12) {
flag ^= 1; flag ^= 1;
...@@ -361,8 +373,11 @@ static int xan_wc3_decode_frame(XanContext *s) { ...@@ -361,8 +373,11 @@ static int xan_wc3_decode_frame(XanContext *s) {
xan_wc3_copy_pixel_run(s, x, y, size, 0, 0); xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
} else { } else {
/* output a run of pixels from imagedata_buffer */ /* output a run of pixels from imagedata_buffer */
if (imagedata_size < size)
break;
xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size); xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
imagedata_buffer += size; imagedata_buffer += size;
imagedata_size -= size;
} }
} else { } else {
/* run-based motion compensation from last frame */ /* run-based motion compensation from last frame */
......
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