/*****************************************************************************
* Preamble
*****************************************************************************/
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
#include "variables.h"
#include "libvlc.h"
+#include "vlc_interface.h"
+
/*****************************************************************************
* Private types
*****************************************************************************/
{
return v.i_time == w.i_time ? 0 : v.i_time > w.i_time ? 1 : -1;
}
-static int CmpString( vlc_value_t v, vlc_value_t w ) { return strcmp( v.psz_string, w.psz_string ); }
+static int CmpString( vlc_value_t v, vlc_value_t w )
+{
+ if( !v.psz_string )
+ return !w.psz_string ? 0 : -1;
+ else
+ return !w.psz_string ? 1 : strcmp( v.psz_string, w.psz_string );
+}
static int CmpFloat( vlc_value_t v, vlc_value_t w ) { return v.f_float == w.f_float ? 0 : v.f_float > w.f_float ? 1 : -1; }
static int CmpAddress( vlc_value_t v, vlc_value_t w ) { return v.p_address == w.p_address ? 0 : v.p_address > w.p_address ? 1 : -1; }
* Local duplication functions, and local deallocation functions
*****************************************************************************/
static void DupDummy( vlc_value_t *p_val ) { (void)p_val; /* unused */ }
-static void DupString( vlc_value_t *p_val ) { p_val->psz_string = strdup( p_val->psz_string ); }
+static void DupString( vlc_value_t *p_val ) { if( p_val->psz_string ) p_val->psz_string = strdup( p_val->psz_string ); }
static void DupList( vlc_value_t *p_val )
{
int i_new;
variable_t *p_var;
static vlc_list_t dummy_null_list = {0, NULL, NULL};
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
+ vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
/* FIXME: if the variable already exists, we don't duplicate it. But we
p_var->choices_text.i_count = 0;
p_var->choices_text.p_values = NULL;
- p_var->b_incallback = VLC_FALSE;
+ p_var->b_incallback = false;
p_var->i_entries = 0;
p_var->p_entries = NULL;
{
case VLC_VAR_BOOL:
p_var->pf_cmp = CmpBool;
- p_var->val.b_bool = VLC_FALSE;
+ p_var->val.b_bool = false;
break;
case VLC_VAR_INTEGER:
case VLC_VAR_HOTKEY:
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 = NULL;
break;
case VLC_VAR_FLOAT:
p_var->pf_cmp = CmpFloat;
p_var->pf_cmp = CmpAddress;
p_var->pf_free = FreeMutex;
p_var->val.p_address = malloc( sizeof(vlc_mutex_t) );
- vlc_mutex_init( p_this, (vlc_mutex_t*)p_var->val.p_address );
+ vlc_mutex_init( (vlc_mutex_t*)p_var->val.p_address );
break;
case VLC_VAR_LIST:
p_var->pf_cmp = CmpAddress;
{
int i_var, i;
variable_t *p_var;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
+ vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = GetUnused( p_this, 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 );
}
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,
int i_var, i;
variable_t *p_var;
vlc_value_t oldval;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
+ vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = Lookup( p_priv->p_vars, p_priv->i_vars, 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 )
{
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 )
{
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-- ; )
}
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 );
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 );
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 );
}
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;
{
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 */
int i_entries = p_var->i_entries;
callback_entry_t *p_entries = p_var->p_entries;
- p_var->b_incallback = VLC_TRUE;
+ p_var->b_incallback = true;
vlc_mutex_unlock( &p_priv->var_lock );
/* The real calls */
}
p_var = &p_priv->p_vars[i_var];
- p_var->b_incallback = VLC_FALSE;
+ p_var->b_incallback = false;
}
}
break;
+ case VLC_VAR_SETISCOMMAND:
+ p_var->i_type |= VLC_VAR_ISCOMMAND;
+ break;
+
default:
break;
}
int __var_Type( vlc_object_t *p_this, const char *psz_name )
{
int i_var, i_type;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_mutex_lock( &p_priv->var_lock );
int i_var;
variable_t *p_var;
vlc_value_t oldval;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
+ vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = GetUnused( p_this, psz_name );
int i_entries = p_var->i_entries;
callback_entry_t *p_entries = p_var->p_entries;
- p_var->b_incallback = VLC_TRUE;
+ p_var->b_incallback = true;
vlc_mutex_unlock( &p_priv->var_lock );
/* The real calls */
}
p_var = &p_priv->p_vars[i_var];
- p_var->b_incallback = VLC_FALSE;
+ p_var->b_incallback = false;
}
/* Free data if needed */
{
int i_var;
variable_t *p_var;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
+ vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );
return NULL;
var_Get( p_global, name, &val );
- vlc_mutex_lock( &val.p_address );
+ vlc_mutex_lock( val.p_address );
return val.p_address;
}
int i_var;
variable_t *p_var;
callback_entry_t entry;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
+ vlc_refcheck( p_this );
entry.pf_callback = pf_callback;
entry.p_data = p_data;
{
int i_entry, i_var;
variable_t *p_var;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
+ vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = GetUnused( p_this, psz_name );
int i_var;
variable_t *p_var;
vlc_value_t oldval;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_mutex_lock( &p_priv->var_lock );
int i_entries = p_var->i_entries;
callback_entry_t *p_entries = p_var->p_entries;
- p_var->b_incallback = VLC_TRUE;
+ p_var->b_incallback = true;
vlc_mutex_unlock( &p_priv->var_lock );
/* The real calls */
}
p_var = &p_priv->p_vars[i_var];
- p_var->b_incallback = VLC_FALSE;
+ p_var->b_incallback = false;
}
vlc_mutex_unlock( &p_priv->var_lock );
* 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;
- vlc_bool_t b_isno = VLC_FALSE;
+ char *psz_name, *psz_value;
+ int i_type;
+ bool b_isno = 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" ) )
}
else goto cleanup; /* Option doesn't exist */
- b_isno = VLC_TRUE;
+ b_isno = 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 )
+ {
+ msg_Err( p_obj, "unsafe option \"%s\" has been ignored for "
+ "security reasons", psz_name );
+ return;
+ }
+ }
+
/* 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. */
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 );
}
static int GetUnused( vlc_object_t *p_this, const char *psz_name )
{
int i_var, i_tries = 0;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
- while( VLC_TRUE )
+ while( true )
{
i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );
if( i_var < 0 )
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:
return VLC_SUCCESS;
}
- vlc_object_internals_t *p_priv = p_this->p_parent->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this->p_parent );
/* Look for the variable */
vlc_mutex_lock( &p_priv->var_lock );
return VLC_ENOOBJ;
}
+ vlc_refcheck( p_this );
i_type = var_Type( p_obj, psz_cmd );
if( !( i_type&VLC_VAR_ISCOMMAND ) )
{