From c5036a3ff8c5f365eb3faac767145f814a958fef Mon Sep 17 00:00:00 2001 From: Tilka Date: Sat, 21 Apr 2012 09:22:06 +0200 Subject: [PATCH] fix random crashes upon !reload A struct plugin_hub_internals was falsely casted to struct plugin_callback_data. This caused the contained commands list pointer to point to a struct hub_info and commands->size took the value of a pointer to a struct net_connection. Since size is increased/decreased every time an item is added to/removed from the list, this resulted in some funny crashes. This fix is a little dirty as it exports some internals. --- src/core/plugincallback.c | 16 +++------------- src/core/pluginloader.c | 9 +-------- src/core/pluginloader.h | 13 ++++++++++--- src/util/list.c | 8 +++++++- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/core/plugincallback.c b/src/core/plugincallback.c index 6c04b99..fb782fb 100644 --- a/src/core/plugincallback.c +++ b/src/core/plugincallback.c @@ -27,10 +27,7 @@ struct plugin_callback_data static struct plugin_callback_data* get_callback_data(struct plugin_handle* plugin) { - struct plugin_callback_data* data; - uhub_assert(plugin && plugin->handle && plugin->handle->internals); - data = (struct plugin_callback_data*) plugin->handle->internals; - return data; + return get_internals(plugin)->callback_data; } static int plugin_command_dispatch(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd) @@ -62,7 +59,6 @@ static struct hub_user* convert_user_type(struct plugin_user* user) static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user* user, const char* message) { -// struct plugin_callback_data* data = get_callback_data(plugin); char* buffer = adc_msg_escape(message); struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6); adc_msg_add_argument(command, buffer); @@ -74,7 +70,6 @@ static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user* static int cbfunc_send_status(struct plugin_handle* plugin, struct plugin_user* user, int code, const char* message) { -// struct plugin_callback_data* data = get_callback_data(plugin); char code_str[4]; char* buffer = adc_msg_escape(message); struct adc_message* command = adc_msg_construct(ADC_CMD_ISTA, strlen(buffer) + 10); @@ -89,7 +84,6 @@ static int cbfunc_send_status(struct plugin_handle* plugin, struct plugin_user* static int cbfunc_user_disconnect(struct plugin_handle* plugin, struct plugin_user* user) { - // struct plugin_callback_data* data = get_callback_data(plugin); hub_disconnect_user(plugin_get_hub(plugin), convert_user_type(user), quit_kicked); return 0; } @@ -224,13 +218,9 @@ void plugin_callback_data_destroy(struct plugin_handle* plugin, struct plugin_ca if (data->commands) { // delete commands not deleted by the plugin itself: - struct plugin_command_handle* cmd = list_get_first(data->commands); - while (cmd) - { + struct plugin_command_handle* cmd; + while ( (cmd = list_get_first(data->commands)) ) cbfunc_command_del(plugin, cmd); - list_remove(data->commands, cmd); - cmd = list_get_next(data->commands); - } list_destroy(data->commands); } diff --git a/src/core/pluginloader.c b/src/core/pluginloader.c index c0fe8a5..107400a 100644 --- a/src/core/pluginloader.c +++ b/src/core/pluginloader.c @@ -23,14 +23,7 @@ struct plugin_callback_data; -struct plugin_hub_internals -{ - struct hub_info* hub; - plugin_unregister_f unregister; /* The unregister function. */ - struct plugin_callback_data* callback_data; /* callback data that is unique for the plugin */ -}; - -static struct plugin_hub_internals* get_internals(struct plugin_handle* handle) +struct plugin_hub_internals* get_internals(struct plugin_handle* handle) { struct plugin_hub_internals* internals; assert(handle && handle->handle && handle->handle->internals); diff --git a/src/core/pluginloader.h b/src/core/pluginloader.h index b2d6143..1929f9b 100644 --- a/src/core/pluginloader.h +++ b/src/core/pluginloader.h @@ -32,7 +32,7 @@ struct uhub_plugin void* handle; plugin_unregister_f unregister; char* filename; - void* internals; // Hub internal stuff + void* internals; // Hub-internal stuff (struct plugin_hub_internals) }; struct uhub_plugins @@ -40,7 +40,7 @@ struct uhub_plugins struct linked_list* loaded; }; -// High level plugin loader ode +// High level plugin loader code extern struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub); extern void plugin_unload(struct plugin_handle* plugin); @@ -54,7 +54,14 @@ extern void plugin_close(struct uhub_plugin*); extern void* plugin_lookup_symbol(struct uhub_plugin*, const char* symbol); // Used internally only +struct plugin_hub_internals +{ + struct hub_info* hub; + plugin_unregister_f unregister; /* The unregister function. */ + struct plugin_callback_data* callback_data; /* callback data that is unique for the plugin */ +}; + +extern struct plugin_hub_internals* get_internals(struct plugin_handle*); extern struct hub_info* plugin_get_hub(struct plugin_handle*); #endif /* HAVE_UHUB_PLUGIN_LOADER_H */ - diff --git a/src/util/list.c b/src/util/list.c index 801c6fa..6d84ed9 100644 --- a/src/util/list.c +++ b/src/util/list.c @@ -32,7 +32,12 @@ struct linked_list* list_create() void list_destroy(struct linked_list* list) { if (list) + { + uhub_assert(list->size == 0); + uhub_assert(list->first == NULL); + uhub_assert(list->last == NULL); hub_free(list); + } } @@ -102,10 +107,11 @@ void list_remove(struct linked_list* list, void* data_ptr) hub_free(node); list->size--; - break; + return; } node = node->next; } + uhub_assert(false); }