mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-13 21:28:01 +02:00
xan: Prevent out of bound accesses
Signed-off-by: Janne Grunau <janne-libav@jannau.net>
This commit is contained in:
parent
14c21c1ff5
commit
124a16f678
@ -218,6 +218,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];
|
||||||
stride = s->current_frame.linesize[0];
|
stride = s->current_frame.linesize[0];
|
||||||
@ -226,7 +230,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);
|
||||||
@ -260,6 +266,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;
|
||||||
|
|
||||||
@ -268,7 +275,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;
|
||||||
@ -293,14 +300,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;
|
||||||
@ -349,6 +359,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;
|
||||||
@ -357,8 +369,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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user