From 393d5031c6aaaf8c2dda4eb5d676974c349fae85 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Sat, 10 Sep 2011 00:32:12 +0200 Subject: Fixed size given to init_get_bits() in xan decoder. --- libavcodec/xan.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'libavcodec/xan.c') diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 2e29e503b2..f20e1095ea 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -95,17 +95,18 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) return 0; } -static int xan_huffman_decode(unsigned char *dest, const unsigned char *src, - int dest_len) +static int xan_huffman_decode(unsigned char *dest, int dest_len, + const unsigned char *src, int src_len) { unsigned char byte = *src++; unsigned char ival = byte + 0x16; const unsigned char * ptr = src + byte*2; + int ptr_len = src_len - 1 - byte*2; unsigned char val = ival; unsigned char *dest_end = dest + dest_len; GetBitContext gb; - init_get_bits(&gb, ptr, 0); // FIXME: no src size available + init_get_bits(&gb, ptr, ptr_len * 8); while ( val != 0x16 ) { val = src[val - 0x17 + get_bits1(&gb) * byte]; @@ -270,7 +271,8 @@ static void xan_wc3_decode_frame(XanContext *s) { vector_segment = s->buf + AV_RL16(&s->buf[4]); imagedata_segment = s->buf + AV_RL16(&s->buf[6]); - xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size); + xan_huffman_decode(opcode_buffer, opcode_buffer_size, + huffman_segment, s->size - (huffman_segment - s->buf) ); if (imagedata_segment[0] == 2) xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size); -- cgit v1.2.3 From 350f57bd7b77b36c150540ad2aae9de42cc4dfca Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 9 Sep 2011 16:13:52 -0700 Subject: xan: Remove extra trailing newline --- libavcodec/xan.c | 1 - 1 file changed, 1 deletion(-) (limited to 'libavcodec/xan.c') diff --git a/libavcodec/xan.c b/libavcodec/xan.c index f20e1095ea..7dc5658c0c 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -563,4 +563,3 @@ AVCodec ff_xan_wc3_decoder = { .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"), }; - -- cgit v1.2.3 From 0872bb23b4bd2d94a8ba91070f706d1bc1c3ced8 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 9 Sep 2011 16:10:03 -0700 Subject: xan: Add some buffer checks --- libavcodec/xan.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'libavcodec/xan.c') diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 7dc5658c0c..ac19c826a5 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -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]) -- cgit v1.2.3