]> git.sesse.net Git - vlc/blobdiff - src/input/input.c
input: fix stack overflow if user feeds an overly large MRL
[vlc] / src / input / input.c
index 77965ac80fdb1240d3d9f90421c827e8be6a3e0e..94b1d766bc5163f1369539e213bca75aaeff8b2b 100644 (file)
@@ -209,6 +209,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
     vlc_mutex_init( &p_input->p->lock_control );
     vlc_cond_init( &p_input->p->wait_control );
     p_input->p->i_control = 0;
+    p_input->p->b_abort = false;
 
     /* Parse input options */
     vlc_mutex_lock( &p_item->lock );
@@ -436,9 +437,11 @@ void input_StopThread( input_thread_t *p_input, bool b_abort )
      * unlock the control loop */
     ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
 
+    vlc_mutex_lock( &p_input->p->lock_control );
+    p_input->p->b_abort |= b_abort;
+    vlc_mutex_unlock( &p_input->p->lock_control );
+
     input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
-    if( b_abort )
-        input_SendEventAbort( p_input );
 }
 
 input_resource_t *input_DetachResource( input_thread_t *p_input )
@@ -508,7 +511,14 @@ static void *Run( vlc_object_t *p_this )
 
 exit:
     /* Tell we're dead */
+    vlc_mutex_lock( &p_input->p->lock_control );
+    const bool b_abort = p_input->p->b_abort;
+    vlc_mutex_unlock( &p_input->p->lock_control );
+
+    if( b_abort )
+        input_SendEventAbort( p_input );
     input_SendEventDead( p_input );
+
     vlc_restorecancel( canc );
     return NULL;
 }
@@ -1234,6 +1244,8 @@ error_stats:
         EXIT_COUNTER( demux_read );
         EXIT_COUNTER( input_bitrate );
         EXIT_COUNTER( demux_bitrate );
+        EXIT_COUNTER( demux_corrupted );
+        EXIT_COUNTER( demux_discontinuity );
         EXIT_COUNTER( played_abuffers );
         EXIT_COUNTER( lost_abuffers );
         EXIT_COUNTER( displayed_pictures );
@@ -1308,6 +1320,8 @@ static void End( input_thread_t * p_input )
             CL_CO( demux_read );
             CL_CO( input_bitrate );
             CL_CO( demux_bitrate );
+            CL_CO( demux_corrupted );
+            CL_CO( demux_discontinuity );
             CL_CO( played_abuffers );
             CL_CO( lost_abuffers );
             CL_CO( displayed_pictures );
@@ -2262,13 +2276,15 @@ static int InputSourceInit( input_thread_t *p_input,
                             input_source_t *in, const char *psz_mrl,
                             const char *psz_forced_demux )
 {
-    char psz_dup[strlen(psz_mrl) + 1];
     const char *psz_access;
     const char *psz_demux;
     char *psz_path;
     double f_fps;
 
-    strcpy( psz_dup, psz_mrl );
+    char *psz_dup = strdup( psz_mrl );
+
+    if( psz_dup == NULL )
+        goto error;
 
     /* Split uri */
     input_SplitMRL( &psz_access, &psz_demux, &psz_path, psz_dup );
@@ -2539,6 +2555,8 @@ static int InputSourceInit( input_thread_t *p_input,
         }
     }
 
+    free( psz_dup );
+
     /* Set record capabilities */
     if( demux_Control( in->p_demux, DEMUX_CAN_RECORD, &in->b_can_stream_record ) )
         in->b_can_stream_record = false;
@@ -2586,6 +2604,7 @@ error:
 
     if( in->p_access )
         access_Delete( in->p_access );
+    free( psz_dup );
 
     return VLC_EGENERIC;
 }