]> git.sesse.net Git - vlc/blobdiff - src/misc/variables.c
Provide the trust value to var_OptionParse
[vlc] / src / misc / variables.c
index 57a9fab269e01c047e63e3a2658e14d7bd35f9b4..df96c3b8d0ef1006bdf98fb4bc8b1a3829e3a8d3 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <vlc/vlc.h>
 #include "variables.h"
 
 #include "libvlc.h"
 
+#include "vlc_interface.h"
+
 /*****************************************************************************
  * Private types
  *****************************************************************************/
@@ -241,7 +247,7 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type )
             p_var->pf_cmp = CmpString;
             p_var->pf_dup = DupString;
             p_var->pf_free = FreeString;
-            p_var->val.psz_string = "";
+            p_var->val.psz_string = strdup( "" );
             break;
         case VLC_VAR_FLOAT:
             p_var->pf_cmp = CmpFloat;
@@ -346,8 +352,7 @@ int __var_Destroy( vlc_object_t *p_this, const char *psz_name )
         for( i = 0 ; i < p_var->choices.i_count ; i++ )
         {
             p_var->pf_free( &p_var->choices.p_values[i] );
-            if( p_var->choices_text.p_values[i].psz_string )
-                free( p_var->choices_text.p_values[i].psz_string );
+            free( p_var->choices_text.p_values[i].psz_string );
         }
         free( p_var->choices.p_values );
         free( p_var->choices_text.p_values );
@@ -360,7 +365,7 @@ int __var_Destroy( vlc_object_t *p_this, const char *psz_name )
     }
 
     free( p_var->psz_name );
-    if( p_var->psz_text ) free( p_var->psz_text );
+    free( p_var->psz_text );
 
     memmove( p_priv->p_vars + i_var,
              p_priv->p_vars + i_var + 1,
@@ -420,6 +425,12 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
             p_var->pf_dup( &p_var->min );
             CheckValue( p_var, &p_var->val );
             break;
+        case VLC_VAR_GETMIN:
+            if( p_var->i_type & VLC_VAR_HASMIN )
+            {
+                *p_val = p_var->min;
+            }
+            break;
         case VLC_VAR_SETMAX:
             if( p_var->i_type & VLC_VAR_HASMAX )
             {
@@ -430,6 +441,12 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
             p_var->pf_dup( &p_var->max );
             CheckValue( p_var, &p_var->val );
             break;
+        case VLC_VAR_GETMAX:
+            if( p_var->i_type & VLC_VAR_HASMAX )
+            {
+                *p_val = p_var->max;
+            }
+            break;
         case VLC_VAR_SETSTEP:
             if( p_var->i_type & VLC_VAR_HASSTEP )
             {
@@ -440,6 +457,12 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
             p_var->pf_dup( &p_var->step );
             CheckValue( p_var, &p_var->val );
             break;
+        case VLC_VAR_GETSTEP:
+            if( p_var->i_type & VLC_VAR_HASSTEP )
+            {
+                *p_val = p_var->step;
+            }
+            break;
         case VLC_VAR_ADDCHOICE:
             /* FIXME: the list is sorted, dude. Use something cleverer. */
             for( i = p_var->choices.i_count ; i-- ; )
@@ -496,8 +519,7 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
             }
 
             p_var->pf_free( &p_var->choices.p_values[i] );
-            if( p_var->choices_text.p_values[i].psz_string )
-                free( p_var->choices_text.p_values[i].psz_string );
+            free( p_var->choices_text.p_values[i].psz_string );
             REMOVE_ELEM( p_var->choices.p_values, p_var->choices.i_count, i );
             REMOVE_ELEM( p_var->choices_text.p_values,
                          p_var->choices_text.i_count, i );
@@ -513,10 +535,8 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
                 p_var->pf_free( &p_var->choices.p_values[i] );
             }
             for( i = 0 ; i < p_var->choices_text.i_count ; i++ )
-            {
-                if( p_var->choices_text.p_values[i].psz_string )
-                    free( p_var->choices_text.p_values[i].psz_string );
-            }
+                free( p_var->choices_text.p_values[i].psz_string );
+
             if( p_var->choices.i_count ) free( p_var->choices.p_values );
             if( p_var->choices_text.i_count ) free( p_var->choices_text.p_values );
 
@@ -596,8 +616,7 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
             if( p_val2 && p_val2->p_list )
             {
                 for( i = 0; i < p_val2->p_list->i_count; i++ )
-                    if( p_val2->p_list->p_values[i].psz_string )
-                        free( p_val2->p_list->p_values[i].psz_string );
+                    free( p_val2->p_list->p_values[i].psz_string );
                 if( p_val2->p_list->i_count )
                 {
                     free( p_val2->p_list->p_values );
@@ -607,7 +626,7 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
             }
             break;
         case VLC_VAR_SETTEXT:
-            if( p_var->psz_text ) free( p_var->psz_text );
+            free( p_var->psz_text );
             if( p_val && p_val->psz_string )
                 p_var->psz_text = strdup( p_val->psz_string );
             break;
@@ -622,7 +641,9 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
             {
                 vlc_value_t val;
 
-                if( InheritValue( p_this, psz_name, &val, p_var->i_type )
+                if( InheritValue( p_this,
+                                  p_val2 ? p_val2->psz_string :  psz_name,
+                                  &val, p_var->i_type )
                     == VLC_SUCCESS )
                 {
                     /* Duplicate already done */
@@ -834,9 +855,10 @@ int __var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val )
 
 
 /**
- * Gets a process-wide mutex, creates it if needed.
+ * Finds a process-wide mutex, creates it if needed, and locks it.
+ * Unlock with vlc_mutex_unlock().
  */
-vlc_mutex_t *var_GetGlobalMutex( const char *name )
+vlc_mutex_t *var_AcquireMutex( const char *name )
 {
     libvlc_global_data_t *p_global = vlc_global();
     vlc_value_t val;
@@ -845,6 +867,7 @@ vlc_mutex_t *var_GetGlobalMutex( const char *name )
         return NULL;
 
     var_Get( p_global, name, &val );
+    vlc_mutex_lock( val.p_address );
     return val.p_address;
 }
 
@@ -1013,30 +1036,34 @@ int __var_TriggerCallback( vlc_object_t *p_this, const char *psz_name )
  * option name and bar is the value of the option.
  * \param p_obj the object in which the variable must be created
  * \param psz_option the option to parse
+ * \param trusted whether the option is set by a trusted input or not
  * \return nothing
  */
-void __var_OptionParse( vlc_object_t *p_obj, const char *psz_option )
+void var_OptionParse( vlc_object_t *p_obj, const char *psz_option,
+                      bool trusted )
 {
-    char *psz_name, *psz_value = strchr( psz_option, '=' );
-    int  i_name_len, i_type;
+    char *psz_name, *psz_value;
+    int  i_type;
     vlc_bool_t b_isno = VLC_FALSE;
     vlc_value_t val;
 
-    if( psz_value ) i_name_len = psz_value - psz_option;
-    else i_name_len = strlen( psz_option );
+    val.psz_string = NULL;
 
     /* It's too much of a hassle to remove the ':' when we parse
      * the cmd line :) */
-    if( i_name_len && *psz_option == ':' )
-    {
+    if( psz_option[0] == ':' )
         psz_option++;
-        i_name_len--;
-    }
 
-    if( i_name_len == 0 ) return;
+    if( !psz_option[0] )
+        return;
 
-    psz_name = strndup( psz_option, i_name_len );
-    if( psz_value ) psz_value++;
+    psz_name = strdup( psz_option );
+    if( psz_name == NULL )
+        return;
+
+    psz_value = strchr( psz_name, '=' );
+    if( psz_value != NULL )
+        *psz_value++ = '\0';
 
     /* FIXME: :programs should be handled generically */
     if( !strcmp( psz_name, "programs" ) )
@@ -1059,14 +1086,42 @@ void __var_OptionParse( vlc_object_t *p_obj, const char *psz_option )
 
         b_isno = VLC_TRUE;
         i_type = config_GetType( p_obj, psz_name );
-
-        if( !i_type ) goto cleanup;  /* Option doesn't exist */
     }
-    else if( !i_type ) goto cleanup; /* Option doesn't exist */
+    if( !i_type ) goto cleanup; /* Option doesn't exist */
 
     if( ( i_type != VLC_VAR_BOOL ) &&
         ( !psz_value || !*psz_value ) ) goto cleanup; /* Invalid value */
 
+    /* check if option is unsafe */
+    if( !trusted )
+    {
+        module_config_t *p_config = config_FindConfig( p_obj, psz_name );
+        if( !p_config->b_safe )
+        {
+            int policy = config_GetInt( p_obj, "security-policy" );
+            switch( policy )
+            {
+                case 0: /* block */
+                    msg_Err( p_obj, "option %s is unsafe and is blocked by security policy", psz_name );
+                    return;
+                case 1: /* allow */
+                    break;
+                case 2: /* prompt */
+                {
+                    char description[256];
+                    snprintf(description, sizeof(description), _("playlist item is making use of the following unsafe option '%s', which may be harmful if used in a malicious way, authorize it ?"), psz_name);
+                    if( DIALOG_OK_YES != intf_UserYesNo( p_obj, _("WARNING: Unsafe Playlist"), description, _("Yes"), _("No"), NULL) )
+                    {
+                        msg_Err( p_obj, "option %s is unsafe and is blocked by security policy", psz_name );
+                        goto cleanup;
+                    }
+                }
+                default:
+                    ;
+            }
+        }
+    }
+
     /* Create the variable in the input object.
      * Children of the input object will be able to retreive this value
      * thanks to the inheritance property of the object variables. */
@@ -1119,20 +1174,18 @@ void __var_OptionParse( vlc_object_t *p_obj, const char *psz_option )
             INSERT_ELEM( p_list->pi_types, p_list->i_count,
                          p_list->i_count, VLC_VAR_INTEGER );
         }
-        if( psz_orig ) free( psz_orig );
+        free( psz_orig );
         break;
     }
 
     default:
         goto cleanup;
-        break;
     }
 
     var_Set( p_obj, psz_name, val );
 
-  cleanup:
-    if( psz_name ) free( psz_name );
-    return;
+cleanup:
+    free( psz_name );
 }
 
 
@@ -1477,7 +1530,7 @@ static int InheritValue( vlc_object_t *p_this, const char *psz_name,
                 INSERT_ELEM( p_list->pi_types, p_list->i_count,
                              p_list->i_count, VLC_VAR_INTEGER );
             }
-            if( psz_orig ) free( psz_orig );
+            free( psz_orig );
             break;
         }
         default: