diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c index 22c2f90de021290d5fc56d39a12c27720670af9d..94d83d18f8b67ab2df5e8345a9f2311acae13b69 100644 --- a/modules/demux/mp4/libmp4.c +++ b/modules/demux/mp4/libmp4.c @@ -104,12 +104,13 @@ } #define MP4_READBOX_EXIT( i_code ) \ - free( p_buff ); \ - if( i_read < 0 ) \ + do \ { \ - msg_Warn( p_stream, "Not enough data" ); \ - } \ - return( i_code ) + free( p_buff ); \ + if( i_read < 0 ) \ + msg_Warn( p_stream, "Not enough data" ); \ + return( i_code ); \ + } while (0) /* Some assumptions: @@ -369,7 +370,6 @@ static int MP4_ReadBoxSkip( stream_t *p_stream, MP4_Box_t *p_box ) static int MP4_ReadBox_ftyp( stream_t *p_stream, MP4_Box_t *p_box ) { - unsigned code = 0; MP4_READBOX_ENTER( MP4_Box_data_ftyp_t ); MP4_GETFOURCC( p_box->data.p_ftyp->i_major_brand ); @@ -383,7 +383,7 @@ static int MP4_ReadBox_ftyp( stream_t *p_stream, MP4_Box_t *p_box ) sizeof(uint32_t)); if( tab == NULL ) - goto error; + MP4_READBOX_EXIT( 0 ); for( i =0; i < p_box->data.p_ftyp->i_compatible_brands_count; i++ ) { @@ -394,10 +394,8 @@ static int MP4_ReadBox_ftyp( stream_t *p_stream, MP4_Box_t *p_box ) { p_box->data.p_ftyp->i_compatible_brands = NULL; } - code = 1; -error: - MP4_READBOX_EXIT( code ); + MP4_READBOX_EXIT( 1 ); } static void MP4_FreeBox_ftyp( MP4_Box_t *p_box ) @@ -598,7 +596,6 @@ static int MP4_ReadBox_mdhd( stream_t *p_stream, MP4_Box_t *p_box ) static int MP4_ReadBox_hdlr( stream_t *p_stream, MP4_Box_t *p_box ) { int32_t i_reserved; - int code = 0; MP4_READBOX_ENTER( MP4_Box_data_hdlr_t ); @@ -616,7 +613,7 @@ static int MP4_ReadBox_hdlr( stream_t *p_stream, MP4_Box_t *p_box ) { uint8_t *psz = p_box->data.p_hdlr->psz_name = malloc( i_read + 1 ); if( psz == NULL ) - goto error; + MP4_READBOX_EXIT( 0 ); /* Yes, I love .mp4 :( */ if( p_box->data.p_hdlr->i_predefined == VLC_FOURCC( 'm', 'h', 'l', 'r' ) ) @@ -643,10 +640,7 @@ static int MP4_ReadBox_hdlr( stream_t *p_stream, MP4_Box_t *p_box ) p_box->data.p_hdlr->psz_name ); #endif - code = 1; - -error: - MP4_READBOX_EXIT( code ); + MP4_READBOX_EXIT( 1 ); } static void MP4_FreeBox_hdlr( MP4_Box_t *p_box ) @@ -793,7 +787,7 @@ static void MP4_FreeBox_stts( MP4_Box_t *p_box ) static int MP4_ReadBox_stts( stream_t *p_stream, MP4_Box_t *p_box ) { - unsigned int i, code = 0; + unsigned int i; MP4_READBOX_ENTER( MP4_Box_data_stts_t ); MP4_GETVERSIONFLAGS( p_box->data.p_stts ); @@ -807,7 +801,7 @@ static int MP4_ReadBox_stts( stream_t *p_stream, MP4_Box_t *p_box ) || p_box->data.p_stts->i_sample_delta == NULL ) { MP4_FreeBox_stts( p_box ); - goto error; + MP4_READBOX_EXIT( 0 ); } for( i = 0; (i < p_box->data.p_stts->i_entry_count )&&( i_read >=8 ); i++ ) @@ -821,9 +815,7 @@ static int MP4_ReadBox_stts( stream_t *p_stream, MP4_Box_t *p_box ) p_box->data.p_stts->i_entry_count ); #endif - code = 1; -error: - MP4_READBOX_EXIT( code ); + MP4_READBOX_EXIT( 1 ); } @@ -835,7 +827,7 @@ static void MP4_FreeBox_ctts( MP4_Box_t *p_box ) static int MP4_ReadBox_ctts( stream_t *p_stream, MP4_Box_t *p_box ) { - unsigned int i, code = 0; + unsigned int i; MP4_READBOX_ENTER( MP4_Box_data_ctts_t ); MP4_GETVERSIONFLAGS( p_box->data.p_ctts ); @@ -850,7 +842,7 @@ static int MP4_ReadBox_ctts( stream_t *p_stream, MP4_Box_t *p_box ) || ( p_box->data.p_ctts->i_sample_offset == NULL ) ) { MP4_FreeBox_ctts( p_box ); - goto error; + MP4_READBOX_EXIT( 0 ); } for( i = 0; (i < p_box->data.p_ctts->i_entry_count )&&( i_read >=8 ); i++ ) @@ -858,15 +850,13 @@ static int MP4_ReadBox_ctts( stream_t *p_stream, MP4_Box_t *p_box ) MP4_GET4BYTES( p_box->data.p_ctts->i_sample_count[i] ); MP4_GET4BYTES( p_box->data.p_ctts->i_sample_offset[i] ); } - code = 1; #ifdef MP4_VERBOSE msg_Dbg( p_stream, "read box: \"ctts\" entry-count %d", p_box->data.p_ctts->i_entry_count ); #endif -error: - MP4_READBOX_EXIT( code ); + MP4_READBOX_EXIT( 1 ); } @@ -1145,8 +1135,10 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box ) */ if( i_read > 0 ) { - p_box->data.p_sample_soun->i_qt_description = i_read; p_box->data.p_sample_soun->p_qt_description = malloc( i_read ); + if( p_box->data.p_sample_soun->p_qt_description == NULL ) + MP4_READBOX_EXIT( 0 ); + p_box->data.p_sample_soun->i_qt_description = i_read; memcpy( p_box->data.p_sample_soun->p_qt_description, p_peek, i_read ); } else @@ -1245,6 +1237,8 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box ) free( p_box->data.p_sample_soun->p_qt_description ); p_box->data.p_sample_soun->p_qt_description = malloc( i_read ); + if( p_box->data.p_sample_soun->p_qt_description == NULL ) + MP4_READBOX_EXIT( 0 ); p_box->data.p_sample_soun->i_qt_description = i_read; memcpy( p_box->data.p_sample_soun->p_qt_description, p_peek, i_read ); } @@ -1298,8 +1292,10 @@ int MP4_ReadBox_sample_vide( stream_t *p_stream, MP4_Box_t *p_box ) */ if( i_read > 0 ) { - p_box->data.p_sample_vide->i_qt_image_description = i_read; p_box->data.p_sample_vide->p_qt_image_description = malloc( i_read ); + if( p_box->data.p_sample_vide->p_qt_image_description == NULL ) + MP4_READBOX_EXIT( 0 ); + p_box->data.p_sample_vide->i_qt_image_description = i_read; memcpy( p_box->data.p_sample_vide->p_qt_image_description, p_peek, i_read ); } @@ -1485,6 +1481,8 @@ static int MP4_ReadBox_stsz( stream_t *p_stream, MP4_Box_t *p_box ) p_box->data.p_stsz->i_entry_size = calloc( p_box->data.p_stsz->i_sample_count, sizeof(uint32_t) ); + if( p_box->data.p_stsz->i_entry_size == NULL ) + MP4_READBOX_EXIT( 0 ); if( !p_box->data.p_stsz->i_sample_size ) { @@ -1508,6 +1506,13 @@ static void MP4_FreeBox_stsz( MP4_Box_t *p_box ) FREENULL( p_box->data.p_stsz->i_entry_size ); } +static void MP4_FreeBox_stsc( MP4_Box_t *p_box ) +{ + FREENULL( p_box->data.p_stsc->i_first_chunk ); + FREENULL( p_box->data.p_stsc->i_samples_per_chunk ); + FREENULL( p_box->data.p_stsc->i_sample_description_index ); +} + static int MP4_ReadBox_stsc( stream_t *p_stream, MP4_Box_t *p_box ) { unsigned int i; @@ -1524,6 +1529,13 @@ static int MP4_ReadBox_stsc( stream_t *p_stream, MP4_Box_t *p_box ) calloc( p_box->data.p_stsc->i_entry_count, sizeof(uint32_t) ); p_box->data.p_stsc->i_sample_description_index = calloc( p_box->data.p_stsc->i_entry_count, sizeof(uint32_t) ); + if( p_box->data.p_stsc->i_first_chunk == NULL + || p_box->data.p_stsc->i_samples_per_chunk == NULL + || p_box->data.p_stsc->i_sample_description_index == NULL ) + { + MP4_FreeBox_stsc( p_box ); + MP4_READBOX_EXIT( 0 ); + } for( i = 0; (i < p_box->data.p_stsc->i_entry_count )&&( i_read >= 12 );i++ ) { @@ -1540,13 +1552,6 @@ static int MP4_ReadBox_stsc( stream_t *p_stream, MP4_Box_t *p_box ) MP4_READBOX_EXIT( 1 ); } -static void MP4_FreeBox_stsc( MP4_Box_t *p_box ) -{ - FREENULL( p_box->data.p_stsc->i_first_chunk ); - FREENULL( p_box->data.p_stsc->i_samples_per_chunk ); - FREENULL( p_box->data.p_stsc->i_sample_description_index ); -} - static int MP4_ReadBox_stco_co64( stream_t *p_stream, MP4_Box_t *p_box ) { unsigned int i; @@ -1559,6 +1564,8 @@ static int MP4_ReadBox_stco_co64( stream_t *p_stream, MP4_Box_t *p_box ) p_box->data.p_co64->i_chunk_offset = calloc( p_box->data.p_co64->i_entry_count, sizeof(uint64_t) ); + if( p_box->data.p_co64->i_chunk_offset == NULL ) + MP4_READBOX_EXIT( 0 ); for( i = 0; i < p_box->data.p_co64->i_entry_count; i++ ) { @@ -1605,6 +1612,8 @@ static int MP4_ReadBox_stss( stream_t *p_stream, MP4_Box_t *p_box ) p_box->data.p_stss->i_sample_number = calloc( p_box->data.p_stss->i_entry_count, sizeof(uint32_t) ); + if( p_box->data.p_stss->i_sample_number == NULL ) + MP4_READBOX_EXIT( 0 ); for( i = 0; (i < p_box->data.p_stss->i_entry_count )&&( i_read >= 4 ); i++ ) { @@ -1627,6 +1636,12 @@ static void MP4_FreeBox_stss( MP4_Box_t *p_box ) FREENULL( p_box->data.p_stss->i_sample_number ); } +static void MP4_FreeBox_stsh( MP4_Box_t *p_box ) +{ + FREENULL( p_box->data.p_stsh->i_shadowed_sample_number ); + FREENULL( p_box->data.p_stsh->i_sync_sample_number ); +} + static int MP4_ReadBox_stsh( stream_t *p_stream, MP4_Box_t *p_box ) { unsigned int i; @@ -1640,10 +1655,15 @@ static int MP4_ReadBox_stsh( stream_t *p_stream, MP4_Box_t *p_box ) p_box->data.p_stsh->i_shadowed_sample_number = calloc( p_box->data.p_stsh->i_entry_count, sizeof(uint32_t) ); - p_box->data.p_stsh->i_sync_sample_number = calloc( p_box->data.p_stsh->i_entry_count, sizeof(uint32_t) ); + if( p_box->data.p_stsh->i_shadowed_sample_number == NULL + || p_box->data.p_stsh->i_sync_sample_number == NULL ) + { + MP4_FreeBox_stsh( p_box ); + MP4_READBOX_EXIT( 0 ); + } for( i = 0; (i < p_box->data.p_stss->i_entry_count )&&( i_read >= 8 ); i++ ) { @@ -1659,12 +1679,6 @@ static int MP4_ReadBox_stsh( stream_t *p_stream, MP4_Box_t *p_box ) MP4_READBOX_EXIT( 1 ); } -static void MP4_FreeBox_stsh( MP4_Box_t *p_box ) -{ - FREENULL( p_box->data.p_stsh->i_shadowed_sample_number ); - FREENULL( p_box->data.p_stsh->i_sync_sample_number ); -} - static int MP4_ReadBox_stdp( stream_t *p_stream, MP4_Box_t *p_box ) { @@ -1696,9 +1710,16 @@ static void MP4_FreeBox_stdp( MP4_Box_t *p_box ) FREENULL( p_box->data.p_stdp->i_priority ); } +static void MP4_FreeBox_padb( MP4_Box_t *p_box ) +{ + FREENULL( p_box->data.p_padb->i_reserved1 ); + FREENULL( p_box->data.p_padb->i_pad2 ); + FREENULL( p_box->data.p_padb->i_reserved2 ); + FREENULL( p_box->data.p_padb->i_pad1 ); +} + static int MP4_ReadBox_padb( stream_t *p_stream, MP4_Box_t *p_box ) { - int code = 0; unsigned int i; uint32_t count; @@ -1706,7 +1727,6 @@ static int MP4_ReadBox_padb( stream_t *p_stream, MP4_Box_t *p_box ) MP4_GETVERSIONFLAGS( p_box->data.p_padb ); - MP4_GET4BYTES( p_box->data.p_padb->i_sample_count ); count = (p_box->data.p_padb->i_sample_count + 1) / 2; @@ -1714,11 +1734,19 @@ static int MP4_ReadBox_padb( stream_t *p_stream, MP4_Box_t *p_box ) p_box->data.p_padb->i_pad2 = calloc( count, sizeof(uint16_t) ); p_box->data.p_padb->i_reserved2 = calloc( count, sizeof(uint16_t) ); p_box->data.p_padb->i_pad1 = calloc( count, sizeof(uint16_t) ); + if( p_box->data.p_padb->i_reserved1 == NULL + || p_box->data.p_padb->i_pad2 == NULL + || p_box->data.p_padb->i_reserved2 == NULL + || p_box->data.p_padb->i_pad1 == NULL ) + { + MP4_FreeBox_padb( p_box ); + MP4_READBOX_EXIT( 0 ); + } for( i = 0; i < i_read / 2 ; i++ ) { if( i >= count ) - goto error; + MP4_READBOX_EXIT( 0 ); p_box->data.p_padb->i_reserved1[i] = ( (*p_peek) >> 7 )&0x01; p_box->data.p_padb->i_pad2[i] = ( (*p_peek) >> 4 )&0x07; p_box->data.p_padb->i_reserved1[i] = ( (*p_peek) >> 3 )&0x01; @@ -1732,17 +1760,15 @@ static int MP4_ReadBox_padb( stream_t *p_stream, MP4_Box_t *p_box ) i_read / 2 ); #endif - code = 1; -error: - MP4_READBOX_EXIT( code ); + MP4_READBOX_EXIT( 1 ); } -static void MP4_FreeBox_padb( MP4_Box_t *p_box ) +static void MP4_FreeBox_elst( MP4_Box_t *p_box ) { - FREENULL( p_box->data.p_padb->i_reserved1 ); - FREENULL( p_box->data.p_padb->i_pad2 ); - FREENULL( p_box->data.p_padb->i_reserved2 ); - FREENULL( p_box->data.p_padb->i_pad1 ); + FREENULL( p_box->data.p_elst->i_segment_duration ); + FREENULL( p_box->data.p_elst->i_media_time ); + FREENULL( p_box->data.p_elst->i_media_rate_integer ); + FREENULL( p_box->data.p_elst->i_media_rate_fraction ); } static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box ) @@ -1762,8 +1788,16 @@ static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box ) calloc( p_box->data.p_elst->i_entry_count, sizeof(uint64_t) ); p_box->data.p_elst->i_media_rate_integer = calloc( p_box->data.p_elst->i_entry_count, sizeof(uint16_t) ); - p_box->data.p_elst->i_media_rate_fraction= + p_box->data.p_elst->i_media_rate_fraction = calloc( p_box->data.p_elst->i_entry_count, sizeof(uint16_t) ); + if( p_box->data.p_elst->i_segment_duration == NULL + || p_box->data.p_elst->i_media_time == NULL + || p_box->data.p_elst->i_media_rate_integer == NULL + || p_box->data.p_elst->i_media_rate_fraction == NULL ) + { + MP4_FreeBox_elst( p_box ); + MP4_READBOX_EXIT( 0 ); + } for( i = 0; i < p_box->data.p_elst->i_entry_count; i++ ) @@ -1795,14 +1829,6 @@ static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box ) MP4_READBOX_EXIT( 1 ); } -static void MP4_FreeBox_elst( MP4_Box_t *p_box ) -{ - FREENULL( p_box->data.p_elst->i_segment_duration ); - FREENULL( p_box->data.p_elst->i_media_time ); - FREENULL( p_box->data.p_elst->i_media_rate_integer ); - FREENULL( p_box->data.p_elst->i_media_rate_fraction ); -} - static int MP4_ReadBox_cprt( stream_t *p_stream, MP4_Box_t *p_box ) { unsigned int i_language; @@ -2023,6 +2049,8 @@ static int MP4_ReadBox_rdrf( stream_t *p_stream, MP4_Box_t *p_box ) { uint32_t i; p_box->data.p_rdrf->psz_ref = malloc( i_len ); + if( p_box->data.p_rdrf->psz_ref == NULL ) + MP4_READBOX_EXIT( 0 ); i_len--; for( i = 0; i < i_len; i++ ) @@ -2164,6 +2192,8 @@ static int MP4_ReadBox_0xa9xxx( stream_t *p_stream, MP4_Box_t *p_box ) if( i_length >= i_read ) i_length = i_read + 1; p_box->data.p_0xa9xxx->psz_text = malloc( i_length ); + if( p_box->data.p_0xa9xxx->psz_text == NULL ) + MP4_READBOX_EXIT( 0 ); i_length--; memcpy( p_box->data.p_0xa9xxx->psz_text, @@ -2201,6 +2231,8 @@ static int MP4_ReadBox_0xa9xxx( stream_t *p_stream, MP4_Box_t *p_box ) // the rest is the text i_data_len -= 12; p_box->data.p_0xa9xxx->psz_text = malloc( i_data_len + 1 ); + if( p_box->data.p_0xa9xxx->psz_text == NULL ) + MP4_READBOX_EXIT( 0 ); memcpy( p_box->data.p_0xa9xxx->psz_text, p_peek, i_data_len ); @@ -2304,7 +2336,9 @@ static int MP4_ReadBox_tref_generic( stream_t *p_stream, MP4_Box_t *p_box ) p_box->data.p_tref_generic->i_track_ID = NULL; p_box->data.p_tref_generic->i_entry_count = i_read / sizeof(uint32_t); if( p_box->data.p_tref_generic->i_entry_count > 0 ) - p_box->data.p_tref_generic->i_track_ID = malloc( p_box->data.p_tref_generic->i_entry_count * sizeof(uint32_t) ); + p_box->data.p_tref_generic->i_track_ID = calloc( p_box->data.p_tref_generic->i_entry_count, sizeof(uint32_t) ); + if( p_box->data.p_tref_generic->i_track_ID == NULL ) + MP4_READBOX_EXIT( 0 ); for( i = 0; i < p_box->data.p_tref_generic->i_entry_count; i++ ) { @@ -2595,6 +2629,9 @@ static MP4_Box_t *MP4_ReadBox( stream_t *p_stream, MP4_Box_t *p_father ) MP4_Box_t *p_box = malloc( sizeof( MP4_Box_t ) ); unsigned int i_index; + if( p_box == NULL ) + return NULL; + if( !MP4_ReadBoxCommon( p_stream, p_box ) ) { msg_Warn( p_stream, "cannot read one box" ); @@ -2698,6 +2735,9 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *s ) int i_result; p_root = malloc( sizeof( MP4_Box_t ) ); + if( p_root == NULL ) + return NULL; + p_root->i_pos = 0; p_root->i_type = VLC_FOURCC( 'r', 'o', 'o', 't' ); p_root->i_shortsize = 1;