| @@ -106,6 +106,9 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, | |||
| unsigned char *dest_end = dest + dest_len; | |||
| GetBitContext gb; | |||
| if (ptr_len < 0) | |||
| return AVERROR_INVALIDDATA; | |||
| init_get_bits(&gb, ptr, ptr_len * 8); | |||
| while ( val != 0x16 ) { | |||
| @@ -245,7 +248,7 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, | |||
| } | |||
| } | |||
| static void xan_wc3_decode_frame(XanContext *s) { | |||
| static int xan_wc3_decode_frame(XanContext *s) { | |||
| int width = s->avctx->width; | |||
| int height = s->avctx->height; | |||
| @@ -265,14 +268,30 @@ static void xan_wc3_decode_frame(XanContext *s) { | |||
| const unsigned char *size_segment; | |||
| const unsigned char *vector_segment; | |||
| const unsigned char *imagedata_segment; | |||
| int huffman_offset, size_offset, vector_offset, imagedata_offset; | |||
| if (s->size < 8) | |||
| return AVERROR_INVALIDDATA; | |||
| huffman_offset = AV_RL16(&s->buf[0]); | |||
| size_offset = AV_RL16(&s->buf[2]); | |||
| vector_offset = AV_RL16(&s->buf[4]); | |||
| imagedata_offset = AV_RL16(&s->buf[6]); | |||
| huffman_segment = s->buf + AV_RL16(&s->buf[0]); | |||
| size_segment = s->buf + AV_RL16(&s->buf[2]); | |||
| vector_segment = s->buf + AV_RL16(&s->buf[4]); | |||
| imagedata_segment = s->buf + AV_RL16(&s->buf[6]); | |||
| if (huffman_offset >= s->size || | |||
| size_offset >= s->size || | |||
| vector_offset >= s->size || | |||
| imagedata_offset >= s->size) | |||
| return AVERROR_INVALIDDATA; | |||
| xan_huffman_decode(opcode_buffer, opcode_buffer_size, | |||
| huffman_segment, s->size - (huffman_segment - s->buf) ); | |||
| huffman_segment = s->buf + huffman_offset; | |||
| size_segment = s->buf + size_offset; | |||
| vector_segment = s->buf + vector_offset; | |||
| imagedata_segment = s->buf + imagedata_offset; | |||
| if (xan_huffman_decode(opcode_buffer, opcode_buffer_size, | |||
| huffman_segment, s->size - huffman_offset) < 0) | |||
| return AVERROR_INVALIDDATA; | |||
| if (imagedata_segment[0] == 2) | |||
| xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size); | |||
| @@ -358,6 +377,7 @@ static void xan_wc3_decode_frame(XanContext *s) { | |||
| y += (x + size) / width; | |||
| x = (x + size) % width; | |||
| } | |||
| return 0; | |||
| } | |||
| #if RUNTIME_GAMMA | |||
| @@ -519,7 +539,8 @@ static int xan_decode_frame(AVCodecContext *avctx, | |||
| s->buf = buf; | |||
| s->size = buf_size; | |||
| xan_wc3_decode_frame(s); | |||
| if (xan_wc3_decode_frame(s) < 0) | |||
| return AVERROR_INVALIDDATA; | |||
| /* release the last frame if it is allocated */ | |||
| if (s->last_frame.data[0]) | |||