1
0
Эх сурвалжийг харах

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.
jp9000 11 жил өмнө
parent
commit
c6300d0956

+ 15 - 3
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)

+ 25 - 0
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

+ 2 - 2
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);
 }
 

+ 2 - 0
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);
 }

+ 4 - 2
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);
 }