]> git.sesse.net Git - vlc/blobdiff - modules/stream_filter/hds/hds.c
hds: fix stale pointer
[vlc] / modules / stream_filter / hds / hds.c
index 55acc20298ffc8c111d14435ac5fee17b41076d8..bc2c4aa97fef544bf455c4fe70d9d13f513b95d2 100644 (file)
@@ -24,6 +24,8 @@
 # include "config.h"
 #endif
 
+#include <limits.h> /* INT_MAX */
+
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_stream.h>
@@ -184,23 +186,24 @@ static bool isHDS( stream_t *s )
     if( i_size < 200 )
         return false;
 
-    const char *str;
+    char *str;
 
     if( !memcmp( peek, "\xFF\xFE", 2 ) )
     {
-        str = FromCharset( "UTF-16LE", peek, 512 );
+        str = FromCharset( "UTF-16LE", peek, i_size );
     }
     else if( !memcmp( peek, "\xFE\xFF", 2 ) )
     {
-        str = FromCharset( "UTF-16BE", peek, 512 );
+        str = FromCharset( "UTF-16BE", peek, i_size );
     }
     else
-        str = peek;
+        str = strndup( peek, i_size );
 
     if( str == NULL )
         return false;
 
     bool ret = strstr( str, "<manifest" ) != NULL;
+    free( str );
     return ret;
 }
 
@@ -581,6 +584,12 @@ static void parse_BootstrapData( vlc_object_t* p_this,
            data_end > data_p &&
            (data_p = parse_asrt( p_this, s, data_p, data_end )) );
 
+    if( ! data_p )
+    {
+        msg_Warn( p_this, "Couldn't find afrt data" );
+        return;
+    }
+
     uint8_t afrt_count = *data_p;
     data_p++;
 
@@ -616,7 +625,7 @@ static void whitespace_substr( char** start,
         return;
 
     while( is_whitespace(*(*end - 1) ) ) {
-        end--;
+        (*end)--;
     }
 }
 
@@ -753,6 +762,8 @@ static uint8_t* download_chunk( stream_t *s,
         msg_Err( s, "Requested %"PRIi64" bytes, "\
                  "but only got %d", size, read );
         data = realloc( chunk->data, read );
+        if( data != NULL )
+            chunk->data = data;
         chunk->failed = true;
         return NULL;
     }
@@ -920,6 +931,7 @@ static chunk_t* generate_new_chunk(
     if( frun_entry == hds_stream->fragment_run_count )
     {
         msg_Err( p_this, "Couldn'd find the fragment run!" );
+        chunk_free( chunk );
         return NULL;
     }
 
@@ -1009,9 +1021,6 @@ static void maintain_live_chunks(
     hds_stream->chunks_head = chunk;
 }
 
-#define SAFE_STRDUP( dest, src, ret )   \
-    if( !( (dest) = strdup( (src) ) ) ) \
-        return (ret)
 
 static void* live_thread( void* p )
 {
@@ -1032,7 +1041,8 @@ static void* live_thread( void* p )
     if( hds_stream->abst_url &&
         ( isFQUrl( hds_stream->abst_url ) ) )
     {
-        SAFE_STRDUP( abst_url, hds_stream->abst_url, NULL );
+        if( !( abst_url = strdup( hds_stream->abst_url ) ) )
+            return NULL;
     }
     else
     {
@@ -1152,9 +1162,11 @@ static int parse_Manifest( stream_t *s )
         {
         case XML_READER_STARTELEM:
             if( current_element_idx == 0 && element_stack[current_element_idx] == 0 ) {
-                SAFE_STRDUP( element_stack[current_element_idx], node, VLC_ENOMEM );
+                if( !( element_stack[current_element_idx] = strdup( node ) ) )
+                    return VLC_ENOMEM;
             } else {
-                SAFE_STRDUP( element_stack[++current_element_idx], node, VLC_ENOMEM );
+                if ( !( element_stack[++current_element_idx] = strdup( node ) ) )
+                    return VLC_ENOMEM;
             }
 
             break;
@@ -1190,41 +1202,47 @@ static int parse_Manifest( stream_t *s )
             {
                 if( !strcmp(attr_name, "streamId" ) )
                 {
-                    SAFE_STRDUP( medias[media_idx].stream_id, attr_value, VLC_ENOMEM );
+                    if( !( medias[media_idx].stream_id = strdup( attr_value ) ) )
+                        return VLC_ENOMEM;
                 }
-                if( !strcmp(attr_name, "url" ) )
+                else if( !strcmp(attr_name, "url" ) )
                 {
-                    SAFE_STRDUP( medias[media_idx].media_url, attr_value, VLC_ENOMEM );
+                    if( !( medias[media_idx].media_url = strdup( attr_value ) ) )
+                        return VLC_ENOMEM;
                 }
-                if( !strcmp(attr_name, "bootstrapInfoId" ) )
+                else if( !strcmp(attr_name, "bootstrapInfoId" ) )
                 {
-                    SAFE_STRDUP( medias[media_idx].bootstrap_id, attr_value, VLC_ENOMEM );
+                    if( !( medias[media_idx].bootstrap_id = strdup( attr_value ) ) )
+                        return VLC_ENOMEM;
                 }
             }
 
             media_idx++;
         }
 
-        if( type == XML_READER_STARTELEM && ! strcmp( current_element, "bootstrapInfo") )
+        else if( type == XML_READER_STARTELEM && ! strcmp( current_element, "bootstrapInfo") )
         {
             while( ( attr_name = xml_ReaderNextAttr( vlc_reader, &attr_value )) )
             {
                 if( !strcmp(attr_name, "url" ) )
                 {
-                    SAFE_STRDUP( bootstraps[bootstrap_idx].url, attr_value, VLC_ENOMEM );
+                    if( !( bootstraps[bootstrap_idx].url = strdup( attr_value ) ) )
+                        return VLC_ENOMEM;
                 }
-                if( !strcmp(attr_name, "id" ) )
+                else if( !strcmp(attr_name, "id" ) )
                 {
-                    SAFE_STRDUP( bootstraps[bootstrap_idx].id, attr_value, VLC_ENOMEM );
+                    if( !( bootstraps[bootstrap_idx].id = strdup( attr_value ) ) )
+                       return VLC_ENOMEM;
                 }
-                if( !strcmp(attr_name, "profile" ) )
+                else if( !strcmp(attr_name, "profile" ) )
                 {
-                    SAFE_STRDUP( bootstraps[bootstrap_idx].profile, attr_value, VLC_ENOMEM );
+                    if( !( bootstraps[bootstrap_idx].profile = strdup( attr_value ) ) )
+                        return VLC_ENOMEM;
                 }
             }
         }
 
-        if( type == XML_READER_TEXT )
+        else if( type == XML_READER_TEXT )
         {
             if( ! strcmp( current_element, "bootstrapInfo" ) )
             {
@@ -1240,17 +1258,17 @@ static int parse_Manifest( stream_t *s )
                     msg_Err( (vlc_object_t*) s, "Couldn't decode bootstrap info" );
                 }
             }
-            if( ! strcmp( current_element, "duration" ) )
+            else if( ! strcmp( current_element, "duration" ) )
             {
                 double shutup_gcc = atof( node );
                 sys->duration_seconds = (uint64_t) shutup_gcc;
             }
-            if( ! strcmp( current_element, "id" ) )
+            else if( ! strcmp( current_element, "id" ) )
             {
-                if( current_element &&
-                    ! strcmp( element_stack[current_element_idx-1], "manifest" ) )
+                if( ! strcmp( element_stack[current_element_idx-1], "manifest" ) )
                 {
-                    SAFE_STRDUP( media_id, node, VLC_ENOMEM );
+                    if( !( media_id = strdup( node ) ) )
+                        return VLC_ENOMEM;
                 }
             }
         }
@@ -1285,7 +1303,11 @@ static int parse_Manifest( stream_t *s )
 
                 if( medias[i].media_url )
                 {
-                    SAFE_STRDUP( new_stream->url, medias[i].media_url, VLC_ENOMEM );
+                    if( !(new_stream->url = strdup( medias[i].media_url ) ) )
+                    {
+                        free(new_stream);
+                        return VLC_ENOMEM;
+                    }
                 }
 
                 if( ! sys->live )
@@ -1312,7 +1334,11 @@ static int parse_Manifest( stream_t *s )
                 }
                 else
                 {
-                    SAFE_STRDUP( new_stream->abst_url, bootstraps[j].url, VLC_ENOMEM );
+                    if( !(new_stream->abst_url = strdup( bootstraps[j].url ) ) )
+                    {
+                        free(new_stream);
+                        return VLC_ENOMEM;
+                    }
                 }
 
                 vlc_array_append( sys->hds_streams, new_stream );
@@ -1345,7 +1371,6 @@ static int parse_Manifest( stream_t *s )
     return VLC_SUCCESS;
 }
 
-#undef SAFE_STRDUP
 
 static void hds_free( hds_stream_t *p_stream )
 {
@@ -1396,17 +1421,20 @@ static int Open( vlc_object_t *p_this )
     if( unlikely( p_sys == NULL ) )
         return VLC_ENOMEM;
 
-    char *uri = NULL;
-    if( unlikely( asprintf( &uri, "%s://%s", s->psz_access, s->psz_path ) < 0 ) )
+    char *uri_without_query = NULL;
+    size_t pathlen = strcspn( s->psz_path, "?" );
+    if( unlikely( ( pathlen > INT_MAX ) ||
+        ( asprintf( &uri_without_query, "%s://%.*s", s->psz_access,
+                    (int)pathlen, s->psz_path ) < 0 ) ) )
     {
         free( p_sys );
         return VLC_ENOMEM;
     }
 
     /* remove the last part of the url */
-    char *pos = strrchr( uri, '/');
+    char *pos = strrchr( uri_without_query, '/');
     *pos = '\0';
-    p_sys->base_url = uri;
+    p_sys->base_url = uri_without_query;
 
     p_sys->flv_header_bytes_sent = 0;