Add a couple more setting data safety measures

Prevent null dereferencing if data is null, instead just make the
functions return and ignore the get/set requests.
This commit is contained in:
jp9000 2014-01-28 15:45:30 -07:00
parent 6c2242dea8
commit c6300d0956
5 changed files with 48 additions and 7 deletions

View File

@ -68,11 +68,17 @@ static inline size_t obs_data_item_total_size(struct obs_data_item *item)
static inline obs_data_t get_item_obj(struct obs_data_item *item)
{
if (!item)
return NULL;
return *(obs_data_t*)get_item_data(item);
}
static inline obs_data_array_t get_item_array(struct obs_data_item *item)
{
if (!item)
return NULL;
return *(obs_data_array_t*)get_item_data(item);
}
@ -233,7 +239,7 @@ obs_data_t obs_data_create_from_json(const char *json_string)
int obs_data_addref(obs_data_t data)
{
return ++data->ref;
return data ? ++data->ref : 0;
}
static inline obs_data_destroy(struct obs_data *data)
@ -270,6 +276,9 @@ const char *obs_data_getjson(obs_data_t data)
static struct obs_data_item *get_item(struct obs_data *data, const char *name)
{
if (!data)
return NULL;
struct obs_data_item *item = data->first_item;
while (item) {
@ -286,12 +295,15 @@ static inline struct obs_data_item *get_item_of(struct obs_data *data,
const char *name, enum obs_data_type type)
{
struct obs_data_item *item = get_item(data, name);
return (item->type == type) ? item : NULL;
return (item && item->type == type) ? item : NULL;
}
static void set_item(struct obs_data *data, const char *name, const void *ptr,
size_t size, enum obs_data_type type)
{
if (!data)
return;
struct obs_data_item *item = get_item(data, name);
if (!item) {
item = obs_data_item_create(name, ptr, size, type);
@ -404,7 +416,7 @@ obs_data_array_t obs_data_array_create()
int obs_data_array_addref(obs_data_array_t array)
{
return ++array->ref;
return array ? ++array->ref : 0;
}
static inline void obs_data_array_destroy(obs_data_array_t array)

View File

@ -123,6 +123,31 @@ EXPORT bool obs_data_item_getbool(obs_data_item_t item, bool def);
EXPORT obs_data_t obs_data_item_getobj(obs_data_item_t item);
EXPORT obs_data_array_t obs_data_item_getarray(obs_data_item_t item);
/* ------------------------------------------------------------------------- */
/* OBS-specific functions */
static inline obs_data_t obs_data_newref(obs_data_t data)
{
if (data)
obs_data_addref(data);
else
data = obs_data_create();
return data;
}
static inline void obs_data_replace(obs_data_t *current, obs_data_t replacement)
{
if (!current)
return;
if (*current != replacement) {
replacement = obs_data_newref(replacement);
obs_data_release(*current);
*current = replacement;
}
}
#ifdef __cplusplus
}
#endif

View File

@ -82,8 +82,7 @@ obs_encoder_t obs_encoder_create(const char *id, const char *name,
return NULL;
}
encoder->settings = settings;
obs_data_addref(settings);
encoder->settings = obs_data_newref(settings);
pthread_mutex_lock(&obs->data.encoders_mutex);
da_push_back(obs->data.encoders, &encoder);
@ -106,6 +105,7 @@ void obs_encoder_destroy(obs_encoder_t encoder)
void obs_encoder_update(obs_encoder_t encoder, obs_data_t settings)
{
obs_data_replace(&encoder->settings, settings);
encoder->callbacks.update(encoder->data, settings);
}

View File

@ -106,6 +106,8 @@ bool obs_output_active(obs_output_t output)
void obs_output_update(obs_output_t output, obs_data_t settings)
{
obs_data_replace(&output->settings, settings);
if (output->callbacks.update)
output->callbacks.update(output->data, settings);
}

View File

@ -111,8 +111,8 @@ bool obs_source_init(struct obs_source *source, obs_data_t settings,
pthread_mutex_init_value(&source->filter_mutex);
pthread_mutex_init_value(&source->video_mutex);
pthread_mutex_init_value(&source->audio_mutex);
source->settings = settings;
obs_data_addref(settings);
source->settings = obs_data_newref(settings);
memcpy(&source->callbacks, info, sizeof(struct source_info));
@ -275,6 +275,8 @@ uint32_t obs_source_get_output_flags(obs_source_t source)
void obs_source_update(obs_source_t source, obs_data_t settings)
{
obs_data_replace(&source->settings, settings);
if (source->callbacks.update)
source->callbacks.update(source->data, settings);
}