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.
This commit is contained in:
Tilka 2012-04-21 09:22:06 +02:00
parent 832277f653
commit c5036a3ff8
4 changed files with 21 additions and 25 deletions

View File

@ -27,10 +27,7 @@ struct plugin_callback_data
static struct plugin_callback_data* get_callback_data(struct plugin_handle* plugin) static struct plugin_callback_data* get_callback_data(struct plugin_handle* plugin)
{ {
struct plugin_callback_data* data; return get_internals(plugin)->callback_data;
uhub_assert(plugin && plugin->handle && plugin->handle->internals);
data = (struct plugin_callback_data*) plugin->handle->internals;
return data;
} }
static int plugin_command_dispatch(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd) 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) 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); char* buffer = adc_msg_escape(message);
struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6); struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer); 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) 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 code_str[4];
char* buffer = adc_msg_escape(message); char* buffer = adc_msg_escape(message);
struct adc_message* command = adc_msg_construct(ADC_CMD_ISTA, strlen(buffer) + 10); 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) 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); hub_disconnect_user(plugin_get_hub(plugin), convert_user_type(user), quit_kicked);
return 0; return 0;
} }
@ -224,13 +218,9 @@ void plugin_callback_data_destroy(struct plugin_handle* plugin, struct plugin_ca
if (data->commands) if (data->commands)
{ {
// delete commands not deleted by the plugin itself: // delete commands not deleted by the plugin itself:
struct plugin_command_handle* cmd = list_get_first(data->commands); struct plugin_command_handle* cmd;
while (cmd) while ( (cmd = list_get_first(data->commands)) )
{
cbfunc_command_del(plugin, cmd); cbfunc_command_del(plugin, cmd);
list_remove(data->commands, cmd);
cmd = list_get_next(data->commands);
}
list_destroy(data->commands); list_destroy(data->commands);
} }

View File

@ -23,14 +23,7 @@
struct plugin_callback_data; struct plugin_callback_data;
struct plugin_hub_internals struct plugin_hub_internals* get_internals(struct plugin_handle* handle)
{
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* internals; struct plugin_hub_internals* internals;
assert(handle && handle->handle && handle->handle->internals); assert(handle && handle->handle && handle->handle->internals);

View File

@ -32,7 +32,7 @@ struct uhub_plugin
void* handle; void* handle;
plugin_unregister_f unregister; plugin_unregister_f unregister;
char* filename; char* filename;
void* internals; // Hub internal stuff void* internals; // Hub-internal stuff (struct plugin_hub_internals)
}; };
struct uhub_plugins struct uhub_plugins
@ -40,7 +40,7 @@ struct uhub_plugins
struct linked_list* loaded; 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 struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub);
extern void plugin_unload(struct plugin_handle* plugin); 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); extern void* plugin_lookup_symbol(struct uhub_plugin*, const char* symbol);
// Used internally only // 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*); extern struct hub_info* plugin_get_hub(struct plugin_handle*);
#endif /* HAVE_UHUB_PLUGIN_LOADER_H */ #endif /* HAVE_UHUB_PLUGIN_LOADER_H */

View File

@ -32,7 +32,12 @@ struct linked_list* list_create()
void list_destroy(struct linked_list* list) void list_destroy(struct linked_list* list)
{ {
if (list) if (list)
{
uhub_assert(list->size == 0);
uhub_assert(list->first == NULL);
uhub_assert(list->last == NULL);
hub_free(list); hub_free(list);
}
} }
@ -102,10 +107,11 @@ void list_remove(struct linked_list* list, void* data_ptr)
hub_free(node); hub_free(node);
list->size--; list->size--;
break; return;
} }
node = node->next; node = node->next;
} }
uhub_assert(false);
} }