[vlc-commits] es_format: return an error if es_format_Copy() partially fails

Rémi Denis-Courmont git at videolan.org
Sat Feb 21 11:24:21 CET 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Feb 21 10:49:10 2015 +0200| [63305f387f445e92b4336cb91f686ff20edfc5f0] | committer: Rémi Denis-Courmont

es_format: return an error if es_format_Copy() partially fails

Consistent with historical semantics, the destination format will
be incomplete but valid if the copy fails. It must be cleared with
es_format_Clean() even in case of error (as before).

Also add a few assertions against invalid formats.

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

 modules/stream_out/cycle.c |    1 +
 src/misc/es_format.c       |  127 ++++++++++++++++++++++++++------------------
 2 files changed, 76 insertions(+), 52 deletions(-)

diff --git a/modules/stream_out/cycle.c b/modules/stream_out/cycle.c
index 51537d1..50bc885 100644
--- a/modules/stream_out/cycle.c
+++ b/modules/stream_out/cycle.c
@@ -80,6 +80,7 @@ static sout_stream_id_sys_t *Add(sout_stream_t *stream, es_format_t *fmt)
 
     if (es_format_Copy(&id->fmt, fmt))
     {
+        es_format_Clean(&id->fmt);
         free(id);
         return NULL;
     }
diff --git a/src/misc/es_format.c b/src/misc/es_format.c
index 215a47a..e15a8b3 100644
--- a/src/misc/es_format.c
+++ b/src/misc/es_format.c
@@ -29,6 +29,8 @@
 # include "config.h"
 #endif
 
+#include <assert.h>
+
 #include <vlc_common.h>
 #include <vlc_es.h>
 
@@ -455,87 +457,108 @@ void es_format_InitFromVideo( es_format_t *p_es, const video_format_t *p_fmt )
     video_format_Copy( &p_es->video, p_fmt );
 }
 
-int es_format_Copy( es_format_t *dst, const es_format_t *src )
+int es_format_Copy(es_format_t *restrict dst, const es_format_t *src)
 {
-    memcpy( dst, src, sizeof( es_format_t ) );
-    dst->psz_language = src->psz_language ? strdup( src->psz_language ) : NULL;
-    dst->psz_description = src->psz_description ? strdup( src->psz_description ) : NULL;
-    if( src->i_extra > 0 && dst->p_extra )
+    int ret = VLC_SUCCESS;
+
+    *dst = *src;
+
+    if (src->psz_language != NULL)
     {
-        dst->i_extra = src->i_extra;
+        dst->psz_language = strdup(src->psz_language);
+        if (unlikely(dst->psz_language == NULL))
+            ret = VLC_ENOMEM;
+    }
+    if (src->psz_description != NULL)
+    {
+        dst->psz_description = strdup(src->psz_description);
+        if (unlikely(dst->psz_description == NULL))
+            ret = VLC_ENOMEM;
+    }
+
+    if (src->i_extra > 0)
+    {
+        assert(src->p_extra != NULL);
         dst->p_extra = malloc( src->i_extra );
-        if(dst->p_extra)
-            memcpy( dst->p_extra, src->p_extra, src->i_extra );
+
+        if( likely(dst->p_extra != NULL) )
+            memcpy(dst->p_extra, src->p_extra, src->i_extra);
         else
+        {
             dst->i_extra = 0;
+            ret = VLC_ENOMEM;
+        }
     }
-    else
+
+    if (src->subs.psz_encoding != NULL)
     {
-        dst->i_extra = 0;
-        dst->p_extra = NULL;
+        dst->subs.psz_encoding = strdup(src->subs.psz_encoding);
+        if (unlikely(dst->subs.psz_encoding == NULL))
+            ret = VLC_ENOMEM;
+    }
+    if (src->subs.p_style != NULL)
+    {
+        dst->subs.p_style = text_style_Duplicate(src->subs.p_style);
+        if (unlikely(dst->subs.p_style == NULL))
+            ret = VLC_ENOMEM;
     }
 
-    dst->subs.psz_encoding = dst->subs.psz_encoding ? strdup( src->subs.psz_encoding ) : NULL;
-    dst->subs.p_style = src->subs.p_style ? text_style_Duplicate( src->subs.p_style ) : NULL;
-
-    if( src->video.p_palette )
+    if (src->video.p_palette != NULL)
     {
-        dst->video.p_palette =
-            (video_palette_t*)malloc( sizeof( video_palette_t ) );
-        if(dst->video.p_palette)
-        {
-            memcpy( dst->video.p_palette, src->video.p_palette,
-                sizeof( video_palette_t ) );
-        }
+        dst->video.p_palette = malloc(sizeof (video_palette_t));
+        if (likely(dst->video.p_palette != NULL))
+            *dst->video.p_palette = *src->video.p_palette;
+        else
+            ret = VLC_ENOMEM;
     }
 
-    if( dst->i_extra_languages && src->p_extra_languages)
+    if (src->i_extra_languages > 0)
     {
-        dst->i_extra_languages = src->i_extra_languages;
-        dst->p_extra_languages = (extra_languages_t*)
-            malloc(dst->i_extra_languages * sizeof(*dst->p_extra_languages ));
-        if( dst->p_extra_languages )
+        assert(src->p_extra_languages != NULL);
+        dst->p_extra_languages = calloc(dst->i_extra_languages,
+                                        sizeof (*dst->p_extra_languages));
+        if (likely(dst->p_extra_languages != NULL))
         {
-            for( unsigned i = 0; i < dst->i_extra_languages; i++ ) {
-                if( src->p_extra_languages[i].psz_language )
-                    dst->p_extra_languages[i].psz_language = strdup( src->p_extra_languages[i].psz_language );
-                else
-                    dst->p_extra_languages[i].psz_language = NULL;
-                if( src->p_extra_languages[i].psz_description )
-                    dst->p_extra_languages[i].psz_description = strdup( src->p_extra_languages[i].psz_description );
-                else
-                    dst->p_extra_languages[i].psz_description = NULL;
+            for (unsigned i = 0; i < dst->i_extra_languages; i++)
+            {
+                if (src->p_extra_languages[i].psz_language != NULL)
+                    dst->p_extra_languages[i].psz_language = strdup(src->p_extra_languages[i].psz_language);
+                if (src->p_extra_languages[i].psz_description != NULL)
+                    dst->p_extra_languages[i].psz_description = strdup(src->p_extra_languages[i].psz_description);
             }
+            dst->i_extra_languages = src->i_extra_languages;
         }
         else
+        {
             dst->i_extra_languages = 0;
+            ret = VLC_ENOMEM;
+        }
     }
-    else
-        dst->i_extra_languages = 0;
-    return VLC_SUCCESS;
+    return ret;
 }
 
-void es_format_Clean( es_format_t *fmt )
+void es_format_Clean(es_format_t *fmt)
 {
-    free( fmt->psz_language );
-    free( fmt->psz_description );
-
-    if( fmt->i_extra > 0 ) free( fmt->p_extra );
+    free(fmt->psz_language);
+    free(fmt->psz_description);
+    assert(fmt->i_extra == 0 || fmt->p_extra != NULL);
+    free(fmt->p_extra);
 
-    free( fmt->video.p_palette );
-    free( fmt->subs.psz_encoding );
+    free(fmt->video.p_palette);
+    free(fmt->subs.psz_encoding);
 
-    if ( fmt->subs.p_style ) text_style_Delete( fmt->subs.p_style );
+    if (fmt->subs.p_style != NULL)
+        text_style_Delete(fmt->subs.p_style);
 
-    for( unsigned i = 0; i < fmt->i_extra_languages; i++ )
+    for (unsigned i = 0; i < fmt->i_extra_languages; i++)
     {
-        free( fmt->p_extra_languages[i].psz_language );
-        free( fmt->p_extra_languages[i].psz_description );
+        free(fmt->p_extra_languages[i].psz_language);
+        free(fmt->p_extra_languages[i].psz_description);
     }
-    free( fmt->p_extra_languages );
+    free(fmt->p_extra_languages);
 
     /* es_format_Clean can be called multiple times */
-    memset( fmt, 0, sizeof(*fmt) );
+    es_format_Init(fmt, UNKNOWN_ES, 0);
 }
 
 bool es_format_IsSimilar( const es_format_t *p_fmt1, const es_format_t *p_fmt2 )



More information about the vlc-commits mailing list