[vlc-devel] commit: Fix crash on exit in vlc_item_Clean. (Jean-Paul Saman )

git version control git at videolan.org
Tue Nov 11 14:44:49 CET 2008


vlc | branch: 0.8.6-bugfix | Jean-Paul Saman <jpsaman at videolan.org> | Fri Nov  7 16:43:02 2008 +0100| [6cb03a1e06d711f3e99775fc6b0b2153d5768be0] | committer: Jean-Paul Saman 

Fix crash on exit in vlc_item_Clean.

Refactored vlc_item_Clean(), vlc_item_CopyOptions() and made sure to properly alloc/free memory and locks.

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

 include/vlc_input.h |   81 +++++++++++++++++++++++++++++----------------------
 src/playlist/item.c |    5 ++-
 2 files changed, 49 insertions(+), 37 deletions(-)

diff --git a/include/vlc_input.h b/include/vlc_input.h
index 55bde9b..143cfa9 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -86,11 +86,11 @@ static inline void vlc_input_item_Init( vlc_object_t *p_o, input_item_t *p_i )
     p_i->i_options  = 0;
     p_i->i_es = 0;
     p_i->i_categories = 0 ;
-    p_i->psz_name = 0;
-    p_i->psz_uri = 0;
-    p_i->ppsz_options = 0;
-    p_i->pp_categories = 0;
-    p_i->es = 0;
+    p_i->psz_name = NULL;
+    p_i->psz_uri = NULL;
+    p_i->ppsz_options = NULL;
+    p_i->pp_categories = NULL;
+    p_i->es = NULL;
     p_i->i_type = ITEM_TYPE_UNKNOWN;
     p_i->b_fixed_name = VLC_TRUE;
 
@@ -106,67 +106,78 @@ static inline void vlc_input_item_CopyOptions( input_item_t *p_parent,
     int i;
     for( i = 0 ; i< p_parent->i_options; i++ )
     {
-        char *psz_option= strdup( p_parent->ppsz_options[i] );
-        p_child->i_options++;
-        p_child->ppsz_options = (char **)realloc( p_child->ppsz_options,
-                                                  p_child->i_options *
-                                                  sizeof( char * ) );
-        p_child->ppsz_options[p_child->i_options-1] = psz_option;
+        char **pp_tmp = NULL;
+        pp_tmp = (char **)realloc( p_child->ppsz_options,
+                                   p_child->i_options+1 *
+                                   sizeof( char * ) );
+        if( pp_tmp )
+        {
+            char *psz_option = strdup( p_parent->ppsz_options[i] );
+            p_child->ppsz_options = pp_tmp;
+            p_child->ppsz_options[p_child->i_options] = psz_option;
+            p_child->i_options++;
+        }
     }
 }
 
 static inline void vlc_input_item_Clean( input_item_t *p_i )
 {
-    if( p_i->psz_name ) free( p_i->psz_name );
-    if( p_i->psz_uri ) free( p_i->psz_uri );
-    if( p_i->p_stats ) free( p_i->p_stats );
-    p_i->psz_name = 0;
-    p_i->psz_uri = 0;
+    vlc_mutex_destroy( &p_i->p_stats->lock );
+
+    free( p_i->psz_name );
+    free( p_i->psz_uri );
+    free( p_i->p_stats );
+
+    p_i->psz_name = NULL;
+    p_i->psz_uri = NULL;
+    p_i->p_stats = NULL;
 
-    while( p_i->i_options )
+    while( p_i->i_options > 0 )
     {
         p_i->i_options--;
-        if( p_i->ppsz_options[p_i->i_options] )
-            free( p_i->ppsz_options[p_i->i_options] );
-        if( !p_i->i_options ) free( p_i->ppsz_options );
+        free( p_i->ppsz_options[p_i->i_options] );
     }
+    free( p_i->ppsz_options );
+    p_i->ppsz_options = NULL;
 
-    while( p_i->i_es )
+    while( p_i->i_es > 0 )
     {
         p_i->i_es--;
         es_format_Clean( p_i->es[p_i->i_es] );
-        if( !p_i->i_es ) free( p_i->es );
     }
+    free( p_i->es );
+    p_i->es = NULL;
 
-    while( p_i->i_categories )
+    while( p_i->i_categories > 0 )
     {
-        info_category_t *p_category =
-            p_i->pp_categories[--(p_i->i_categories)];
+        info_category_t *p_category;
+
+        p_i->i_categories--;
+        p_category = p_i->pp_categories[p_i->i_categories];
 
         while( p_category->i_infos )
         {
             p_category->i_infos--;
 
-            if( p_category->pp_infos[p_category->i_infos]->psz_name )
-                free( p_category->pp_infos[p_category->i_infos]->psz_name);
-            if( p_category->pp_infos[p_category->i_infos]->psz_value )
-                free( p_category->pp_infos[p_category->i_infos]->psz_value );
+            free( p_category->pp_infos[p_category->i_infos]->psz_name );
+            free( p_category->pp_infos[p_category->i_infos]->psz_value );
             free( p_category->pp_infos[p_category->i_infos] );
-
-            if( !p_category->i_infos ) free( p_category->pp_infos );
         }
+        free( p_category->pp_infos );
+        p_category->pp_infos = NULL;
 
-        if( p_category->psz_name ) free( p_category->psz_name );
+        free( p_category->psz_name );
         free( p_category );
-
-        if( !p_i->i_categories ) free( p_i->pp_categories );
+        p_category = NULL;
     }
+    free( p_i->pp_categories );
+    p_i->pp_categories = NULL;
 
     vlc_mutex_destroy( &p_i->lock );
 }
 
 VLC_EXPORT( char *, vlc_input_item_GetInfo, ( input_item_t *p_i, const char *psz_cat,const char *psz_name ) );
-VLC_EXPORT(int, vlc_input_item_AddInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name, const char *psz_format, ... ) );
+VLC_EXPORT( int, vlc_input_item_AddInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name, const char *psz_format, ... ) );
 
 /*****************************************************************************
  * Seek point: (generalisation of chapters)
diff --git a/src/playlist/item.c b/src/playlist/item.c
index e9ce3db..283a63e 100644
--- a/src/playlist/item.c
+++ b/src/playlist/item.c
@@ -191,9 +191,10 @@ int playlist_ItemDelete( playlist_item_t *p_item )
 {
     for( ; p_item->i_parents > 0 ; )
     {
-        struct item_parent_t *p_parent =  p_item->pp_parents[0];
+        struct item_parent_t *p_parent = p_item->pp_parents[0];
         REMOVE_ELEM( p_item->pp_parents, p_item->i_parents, 0 );
         free( p_parent );
+        p_parent = NULL;
     }
 
     for( ; p_item->i_children > 0 ; )
@@ -205,7 +206,7 @@ int playlist_ItemDelete( playlist_item_t *p_item )
 
     vlc_input_item_Clean( &p_item->input );
     free( p_item );
-
+    p_item = NULL;
     return VLC_SUCCESS;
 }
 




More information about the vlc-devel mailing list