cinepak: do not access arrays beyond allocated size
authorRafaël Carré <funman@videolan.org>
Mon, 24 Mar 2008 20:19:05 +0000 (21:19 +0100)
committerRafaël Carré <funman@videolan.org>
Tue, 25 Mar 2008 23:36:09 +0000 (00:36 +0100)
reported by Drew Yao

modules/codec/cinepak.c

index 68dffcf..75d103a 100644 (file)
@@ -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; */