[vlc-commits] demux: libmp4: fix invalid tfra values reading

Francois Cartegnie git at videolan.org
Tue Oct 21 19:07:14 CEST 2014


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Oct 21 19:02:47 2014 +0200| [cc356c39293c63ecfe1a6e4516b41d6a3ef44a37] | committer: Francois Cartegnie

demux: libmp4: fix invalid tfra values reading

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=cc356c39293c63ecfe1a6e4516b41d6a3ef44a37
---

 modules/demux/mp4/libmp4.c |   88 +++++++++++++++++---------------------------
 1 file changed, 34 insertions(+), 54 deletions(-)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 73ec73e..5f02754 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -3294,6 +3294,25 @@ static int MP4_ReadBox_mfro( stream_t *p_stream, MP4_Box_t *p_box )
 
 static int MP4_ReadBox_tfra( stream_t *p_stream, MP4_Box_t *p_box )
 {
+#define READ_VARIABLE_LENGTH(lengthvar, p_array) switch (lengthvar)\
+{\
+    case 0:\
+        MP4_GET1BYTE( p_array[i] );\
+        break;\
+    case 1:\
+        MP4_GET2BYTES( *((uint16_t *)&p_array[i*2]) );\
+        break;\
+    case 2:\
+        MP4_GET3BYTES( *((uint32_t *)&p_array[i*4]) );\
+        break;\
+    case 3:\
+        MP4_GET4BYTES( *((uint32_t *)&p_array[i*4]) );\
+        break;\
+    default:\
+        goto error;\
+}
+#define FIX_VARIABLE_LENGTH(lengthvar) if ( lengthvar == 3 ) lengthvar = 4
+
     uint32_t i_number_of_entries;
     MP4_READBOX_ENTER( MP4_Box_data_tfra_t );
     MP4_Box_data_tfra_t *p_tfra = p_box->data.p_tfra;
@@ -3314,10 +3333,13 @@ static int MP4_ReadBox_tfra( stream_t *p_stream, MP4_Box_t *p_box )
     p_tfra->p_moof_offset = calloc( i_number_of_entries, size );
 
     size = 1 + p_tfra->i_length_size_of_traf_num; /* size in [|1, 4|] */
+    if ( size == 3 ) size++;
     p_tfra->p_traf_number = calloc( i_number_of_entries, size );
     size = 1 + p_tfra->i_length_size_of_trun_num;
+    if ( size == 3 ) size++;
     p_tfra->p_trun_number = calloc( i_number_of_entries, size );
     size = 1 + p_tfra->i_length_size_of_sample_num;
+    if ( size == 3 ) size++;
     p_tfra->p_sample_number = calloc( i_number_of_entries, size );
 
     if( !p_tfra->p_time || !p_tfra->p_moof_offset || !p_tfra->p_traf_number
@@ -3336,8 +3358,8 @@ static int MP4_ReadBox_tfra( stream_t *p_stream, MP4_Box_t *p_box )
         {
             if ( i_read < i_fields_length + 16 )
                 break;
-            MP4_GET8BYTES( p_tfra->p_time[i*2] );
-            MP4_GET8BYTES( p_tfra->p_moof_offset[i*2] );
+            MP4_GET8BYTES( *((uint64_t *)&p_tfra->p_time[i*2]) );
+            MP4_GET8BYTES( *((uint64_t *)&p_tfra->p_moof_offset[i*2]) );
         }
         else
         {
@@ -3346,63 +3368,18 @@ static int MP4_ReadBox_tfra( stream_t *p_stream, MP4_Box_t *p_box )
             MP4_GET4BYTES( p_tfra->p_time[i] );
             MP4_GET4BYTES( p_tfra->p_moof_offset[i] );
         }
-        switch (p_tfra->i_length_size_of_traf_num)
-        {
-            case 0:
-                MP4_GET1BYTE( p_tfra->p_traf_number[i] );
-                break;
-            case 1:
-                MP4_GET2BYTES( p_tfra->p_traf_number[i*2] );
-                break;
-            case 2:
-                MP4_GET3BYTES( p_tfra->p_traf_number[i*3] );
-                break;
-            case 3:
-                MP4_GET4BYTES( p_tfra->p_traf_number[i*4] );
-                break;
-            default:
-                goto error;
-        }
-
-        switch (p_tfra->i_length_size_of_trun_num)
-        {
-            case 0:
-                MP4_GET1BYTE( p_tfra->p_trun_number[i] );
-                break;
-            case 1:
-                MP4_GET2BYTES( p_tfra->p_trun_number[i*2] );
-                break;
-            case 2:
-                MP4_GET3BYTES( p_tfra->p_trun_number[i*3] );
-                break;
-            case 3:
-                MP4_GET4BYTES( p_tfra->p_trun_number[i*4] );
-                break;
-            default:
-                goto error;
-        }
 
-        switch (p_tfra->i_length_size_of_sample_num)
-        {
-            case 0:
-                MP4_GET1BYTE( p_tfra->p_sample_number[i] );
-                break;
-            case 1:
-                MP4_GET2BYTES( p_tfra->p_sample_number[i*2] );
-                break;
-            case 2:
-                MP4_GET3BYTES( p_tfra->p_sample_number[i*3] );
-                break;
-            case 3:
-                MP4_GET4BYTES( p_tfra->p_sample_number[i*4] );
-                break;
-            default:
-                goto error;
-        }
+        READ_VARIABLE_LENGTH(p_tfra->i_length_size_of_traf_num, p_tfra->p_traf_number);
+        READ_VARIABLE_LENGTH(p_tfra->i_length_size_of_trun_num, p_tfra->p_trun_number);
+        READ_VARIABLE_LENGTH(p_tfra->i_length_size_of_sample_num, p_tfra->p_sample_number);
     }
     if ( i < i_number_of_entries )
         i_number_of_entries = i;
 
+    FIX_VARIABLE_LENGTH(p_tfra->i_length_size_of_traf_num);
+    FIX_VARIABLE_LENGTH(p_tfra->i_length_size_of_trun_num);
+    FIX_VARIABLE_LENGTH(p_tfra->i_length_size_of_sample_num);
+
 #ifdef MP4_ULTRA_VERBOSE
     for( i = 0; i < i_number_of_entries; i++ )
     {
@@ -3432,6 +3409,9 @@ static int MP4_ReadBox_tfra( stream_t *p_stream, MP4_Box_t *p_box )
     MP4_READBOX_EXIT( 1 );
 error:
     MP4_READBOX_EXIT( 0 );
+
+#undef READ_VARIABLE_LENGTH
+#undef FIX_VARIABLE_LENGTH
 }
 
 static void MP4_FreeBox_tfra( MP4_Box_t *p_box )



More information about the vlc-commits mailing list