[vlc-commits] gvp: fix leaks and integer overflow on multi-lines

Rémi Denis-Courmont git at videolan.org
Mon Nov 17 18:03:26 CET 2014


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Nov 17 18:33:02 2014 +0200| [dee1ccf02c28d4fa02f8b813b37cc0462d57d95d] | committer: Rémi Denis-Courmont

gvp: fix leaks and integer overflow on multi-lines

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

 modules/demux/playlist/gvp.c |   73 +++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 43 deletions(-)

diff --git a/modules/demux/playlist/gvp.c b/modules/demux/playlist/gvp.c
index 5b17967..e28e09b 100644
--- a/modules/demux/playlist/gvp.c
+++ b/modules/demux/playlist/gvp.c
@@ -97,13 +97,13 @@ int Import_GVP( vlc_object_t *p_this )
 static int Demux( demux_t *p_demux )
 {
     char *psz_line;
-    char *psz_attrvalue;
 
     char *psz_version = NULL;
     char *psz_url = NULL;
     char *psz_docid = NULL;
     char *psz_title = NULL;
-    char *psz_description = NULL;
+    char *psz_desc = NULL;
+    size_t desclen = 0;
     input_item_t *p_input;
 
     input_item_t *p_current_input = GetCurrentItem(p_demux);
@@ -118,54 +118,41 @@ static int Demux( demux_t *p_demux )
             free( psz_line );
             continue;
         }
-        psz_attrvalue = strchr( psz_line, ':' );
-        if( !psz_attrvalue )
+
+        char *value = strchr( psz_line, ':' );
+        if( value == NULL )
         {
             msg_Dbg( p_demux, "Unable to parse line (%s)", psz_line );
             free( psz_line );
             continue;
         }
-        *psz_attrvalue = '\0';
-        psz_attrvalue++;
-        if( !strcmp( psz_line, "gvp_version" ) )
-        {
-            psz_version = strdup( psz_attrvalue );
-        }
-        else if( !strcmp( psz_line, "url" ) )
-        {
-            psz_url = strdup( psz_attrvalue );
-        }
-        else if( !strcmp( psz_line, "docid" ) )
-        {
-            psz_docid = strdup( psz_attrvalue );
-        }
+        *(value++) = '\0';
+
+        size_t len = strlen( value );
+        if( len > 0 && value[len - 1] == '\r' )
+            value[--len] = '\0'; /* strip trailing CR */
+
+        if( psz_version == NULL && !strcmp( psz_line, "gvp_version" ) )
+            psz_version = strdup( value );
+        else if( psz_url == NULL && !strcmp( psz_line, "url" ) )
+            psz_url = strdup( value );
+        else if( psz_docid == NULL && !strcmp( psz_line, "docid" ) )
+            psz_docid = strdup( value );
         else if( !strcmp( psz_line, "duration" ) )
             /*atoi( psz_attrvalue )*/;
-        else if( !strcmp( psz_line, "title" ) )
+        else if( psz_title == NULL && !strcmp( psz_line, "title" ) )
+            psz_title = strdup( value );
+        else if( !strcmp( psz_line, "description" )
+              && desclen < 32768 && len < 32768 )
         {
-            psz_title = strdup( psz_attrvalue );
-        }
-        else if( !strcmp( psz_line, "description" ) )
-        {
-            char *buf;
-            if( !psz_description )
-            {
-                psz_description = strdup( psz_attrvalue );
-            }
-            else
-            {
-                /* handle multi-line descriptions */
-                if( asprintf( &buf, "%s\n%s", psz_description, psz_attrvalue ) == -1 )
-                    buf = NULL;
-                free( psz_description );
-                psz_description = buf;
-            }
-            /* remove ^M char at the end of the line (if any) */
-            buf = psz_description + strlen( psz_description );
-            if( buf != psz_description )
+            char *buf = realloc( psz_desc, desclen + 1 + len + 1 );
+            if( buf != NULL )
             {
-                buf--;
-                if( *buf == '\r' ) *buf = '\0';
+                if( desclen > 0 )
+                    buf[desclen++] = '\n';
+                memcpy( buf + desclen, value, len + 1 );
+                desclen += len;
+                psz_desc = buf;
             }
         }
         free( psz_line );
@@ -182,7 +169,7 @@ static int Demux( demux_t *p_demux )
                     p_input, _("Google Video"), type, "%s", field ) ; }
         SADD_INFO( "gvp_version", psz_version );
         SADD_INFO( "docid", psz_docid );
-        SADD_INFO( "description", psz_description );
+        SADD_INFO( "description", psz_desc );
         input_item_node_AppendItem( p_subitems, p_input );
         vlc_gc_decref( p_input );
     }
@@ -195,7 +182,7 @@ static int Demux( demux_t *p_demux )
     free( psz_url );
     free( psz_docid );
     free( psz_title );
-    free( psz_description );
+    free( psz_desc );
 
     return 0; /* Needed for correct operation of go back */
 }



More information about the vlc-commits mailing list