From c6300d095691b00c54d4fb6b122849f0e4010a7e Mon Sep 17 00:00:00 2001 From: jp9000 Date: Tue, 28 Jan 2014 15:45:30 -0700 Subject: [PATCH] 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. --- libobs/obs-data.c | 18 +++++++++++++++--- libobs/obs-data.h | 25 +++++++++++++++++++++++++ libobs/obs-encoder.c | 4 ++-- libobs/obs-output.c | 2 ++ libobs/obs-source.c | 6 ++++-- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/libobs/obs-data.c b/libobs/obs-data.c index 7000e689f..497143b4f 100644 --- a/libobs/obs-data.c +++ b/libobs/obs-data.c @@ -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) diff --git a/libobs/obs-data.h b/libobs/obs-data.h index 0375dba3c..b31f9285c 100644 --- a/libobs/obs-data.h +++ b/libobs/obs-data.h @@ -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 diff --git a/libobs/obs-encoder.c b/libobs/obs-encoder.c index c382ed4ac..ee15b2441 100644 --- a/libobs/obs-encoder.c +++ b/libobs/obs-encoder.c @@ -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); } diff --git a/libobs/obs-output.c b/libobs/obs-output.c index 357d4a1fb..76fa729af 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -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); } diff --git a/libobs/obs-source.c b/libobs/obs-source.c index b52522d15..8e9e6052c 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -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); }