X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fvariables.c;h=ed5f31a03d50b9ae628a9b45f85a7782f04ade39;hb=23fe953dbb391d1a20a6b75a79d41ff8a2d77f82;hp=5f83f848f368f10e831a0f31359f8af642d15875;hpb=262c049bddab97077b49e00600a33ccd242d052d;p=vlc diff --git a/src/misc/variables.c b/src/misc/variables.c index 5f83f848f3..ed5f31a03d 100644 --- a/src/misc/variables.c +++ b/src/misc/variables.c @@ -28,7 +28,7 @@ # include "config.h" #endif -#include +#include #include "variables.h" #include "libvlc.h" @@ -53,7 +53,13 @@ static int CmpTime( vlc_value_t v, vlc_value_t w ) { 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; } @@ -61,7 +67,7 @@ static int CmpAddress( vlc_value_t v, vlc_value_t w ) { return v.p_address == w. * 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 ) { @@ -160,8 +166,9 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) 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 @@ -221,7 +228,7 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) 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; @@ -232,7 +239,7 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) { 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: @@ -247,7 +254,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 = strdup( "" ); + p_var->val.psz_string = NULL; break; case VLC_VAR_FLOAT: p_var->pf_cmp = CmpFloat; @@ -265,7 +272,7 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) 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; @@ -323,8 +330,9 @@ int __var_Destroy( vlc_object_t *p_this, const char *psz_name ) { 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 ); @@ -352,8 +360,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 ); @@ -366,7 +373,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, @@ -400,8 +407,9 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, 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 ); @@ -465,22 +473,7 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, } break; case VLC_VAR_ADDCHOICE: - /* FIXME: the list is sorted, dude. Use something cleverer. */ - for( i = p_var->choices.i_count ; i-- ; ) - { - if( p_var->pf_cmp( p_var->choices.p_values[i], *p_val ) < 0 ) - { - break; - } - } - - /* The new place is i+1 */ - i++; - - if( p_var->i_default >= i ) - { - p_var->i_default++; - } + i = p_var->choices.i_count; INSERT_ELEM( p_var->choices.p_values, p_var->choices.i_count, i, *p_val ); @@ -494,7 +487,6 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, CheckValue( p_var, &p_var->val ); break; case VLC_VAR_DELCHOICE: - /* FIXME: the list is sorted, dude. Use something cleverer. */ for( i = 0 ; i < p_var->choices.i_count ; i++ ) { if( p_var->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 ) @@ -520,8 +512,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 ); @@ -537,10 +528,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 ); @@ -620,8 +609,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 ); @@ -631,7 +619,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; @@ -680,7 +668,7 @@ int __var_Change( vlc_object_t *p_this, const char *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 */ @@ -701,11 +689,15 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, } 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; } @@ -725,7 +717,7 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, 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 ); @@ -756,8 +748,9 @@ int __var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val ) 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 ); @@ -789,7 +782,7 @@ int __var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val ) 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 */ @@ -810,7 +803,7 @@ int __var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val ) } p_var = &p_priv->p_vars[i_var]; - p_var->b_incallback = VLC_FALSE; + p_var->b_incallback = false; } /* Free data if needed */ @@ -833,8 +826,9 @@ int __var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val ) { 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 ); @@ -899,8 +893,9 @@ int __var_AddCallback( vlc_object_t *p_this, const char *psz_name, 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; @@ -936,8 +931,9 @@ int __var_DelCallback( vlc_object_t *p_this, const char *psz_name, { 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 ); @@ -982,7 +978,7 @@ int __var_TriggerCallback( vlc_object_t *p_this, const char *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 ); @@ -1006,7 +1002,7 @@ int __var_TriggerCallback( vlc_object_t *p_this, const char *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 */ @@ -1027,7 +1023,7 @@ int __var_TriggerCallback( vlc_object_t *p_this, const char *psz_name ) } 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 ); @@ -1041,31 +1037,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; - vlc_bool_t b_isno = VLC_FALSE; + char *psz_name, *psz_value; + int i_type; + bool b_isno = false; vlc_value_t val; - val.psz_string = NULL; - 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 = strdup( psz_option ); + if( psz_name == NULL ) + return; - psz_name = strndup( psz_option, i_name_len ); - if( psz_value ) psz_value++; + psz_value = strchr( psz_name, '=' ); + if( psz_value != NULL ) + *psz_value++ = '\0'; /* FIXME: :programs should be handled generically */ if( !strcmp( psz_name, "programs" ) ) @@ -1086,42 +1085,23 @@ void __var_OptionParse( vlc_object_t *p_obj, const char *psz_option ) } 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 ) + 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 ); - return; - } - } - default: - ; - } + msg_Err( p_obj, "unsafe option \"%s\" has been ignored for " + "security reasons", psz_name ); + return; } } @@ -1177,20 +1157,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 ); } @@ -1205,9 +1183,9 @@ void __var_OptionParse( vlc_object_t *p_obj, const char *psz_option ) 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 ) @@ -1535,7 +1513,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: @@ -1546,7 +1524,7 @@ static int InheritValue( vlc_object_t *p_this, const char *psz_name, 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 ); @@ -1592,6 +1570,7 @@ int __var_Command( vlc_object_t *p_this, const char *psz_name, return VLC_ENOOBJ; } + vlc_refcheck( p_this ); i_type = var_Type( p_obj, psz_cmd ); if( !( i_type&VLC_VAR_ISCOMMAND ) ) {