From: Rafaël Carré Date: Mon, 24 Mar 2008 20:19:05 +0000 (+0100) Subject: cinepak: do not access arrays beyond allocated size X-Git-Tag: 0.9.0-test0~1877 X-Git-Url: http://git.videolan.org/gitweb.cgi/vlc.git/?p=vlc.git;p=vlc.git;a=commitdiff_plain;h=d7e6e4afcecea38831282152d6e7af9a62989985 cinepak: do not access arrays beyond allocated size reported by Drew Yao --- diff --git a/modules/codec/cinepak.c b/modules/codec/cinepak.c index 68dffcff4a..75d103a6d7 100644 --- a/modules/codec/cinepak.c +++ b/modules/codec/cinepak.c @@ -63,8 +63,8 @@ typedef struct { int b_grayscale; /* force to grayscale */ - int i_width; - int i_height; + unsigned int i_width; + unsigned int i_height; int i_stride_x; int i_stride_y; @@ -93,7 +93,7 @@ struct decoder_sys_t static picture_t *DecodeBlock ( decoder_t *, block_t ** ); -static int cinepak_decode_frame( cinepak_context_t *, int, uint8_t * ); +static int cinepak_decode_frame( cinepak_context_t *, size_t, uint8_t * ); /***************************************************************************** * OpenDecoder: probe the decoder and return score @@ -281,6 +281,16 @@ static void cinepak_Getv4( cinepak_context_t *p_context, uint8_t i_index[4]; int i,j; + size_t y_max = p_context->i_stride[0] * ( i_y + 5 ) + i_x + 5; + size_t u_max = p_context->i_stride[1] * ( ( i_y/2 ) + 2 ) + 2 + ( i_x / 2 ); + size_t v_max = p_context->i_stride[2] * ( ( i_y/2 ) + 2 ) + 2 + ( i_x / 2 ); + size_t y_siz = p_context->i_stride[0] * p_context->i_lines[0]; + size_t u_siz = p_context->i_stride[1] * p_context->i_lines[1]; + size_t v_siz = p_context->i_stride[2] * p_context->i_lines[2]; + /* boundary check */ + if( y_max >= y_siz || u_max >= u_siz || v_max >= v_siz ) + return; + uint8_t *p_dst_y, *p_dst_u, *p_dst_v; #define PIX_SET_Y( x, y, v ) \ p_dst_y[(x) + (y)* p_context->i_stride[0]] = (v); @@ -328,6 +338,16 @@ static void cinepak_Getv1( cinepak_context_t *p_context, uint8_t i_index; int i,j; + size_t y_max = p_context->i_stride[0] * ( i_y + 5 ) + i_x + 5; + size_t u_max = p_context->i_stride[1] * ( ( i_y/2 ) + 2 ) + 2 + ( i_x / 2 ); + size_t v_max = p_context->i_stride[2] * ( ( i_y/2 ) + 2 ) + 2 + ( i_x / 2 ); + size_t y_siz = p_context->i_stride[0] * p_context->i_lines[0]; + size_t u_siz = p_context->i_stride[1] * p_context->i_lines[1]; + size_t v_siz = p_context->i_stride[2] * p_context->i_lines[2]; + /* boundary check */ + if( y_max >= y_siz || u_max >= u_siz || v_max >= v_siz ) + return; + uint8_t *p_dst_y, *p_dst_u, *p_dst_v; #define PIX_SET_Y( x, y, v ) \ p_dst_y[(x) + (y)* p_context->i_stride[0]] = (v); @@ -370,14 +390,14 @@ static void cinepak_Getv1( cinepak_context_t *p_context, * The function that decode one frame *****************************************************************************/ static int cinepak_decode_frame( cinepak_context_t *p_context, - int i_length, uint8_t *p_data ) + size_t i_length, uint8_t *p_data ) { int i_strip; - int i_frame_flags; - int i_frame_size; - int i_width, i_height; - int i_frame_strips; + int8_t i_frame_flags; + uint32_t i_frame_size; + uint16_t i_width, i_height; + uint16_t i_frame_strips; int i_index; int i_strip_x1 =0, i_strip_y1=0; int i_strip_x2 =0, i_strip_y2=0; @@ -447,15 +467,15 @@ static int cinepak_decode_frame( cinepak_context_t *p_context, /* Now decode each strip */ for( i_strip = 0; i_strip < i_frame_strips; i_strip++ ) { - int i_strip_id; - int i_strip_size; + uint16_t i_strip_size; if( i_length <= 12 ) { break; } - i_strip_id = GET2BYTES( p_data ); + p_data += 2; /* int16_t i_strip_id = GET2BYTES( p_data ); */ + i_strip_size = GET2BYTES( p_data ); i_strip_size = __MIN( i_strip_size, i_length ); /* FIXME I don't really understand how it works; */