# HG changeset patch # User Jeffrey Connelly # Date 1203899123 0 # Node ID 9479cf89a97d05c46661bb05a2234dec6a5d630a # Parent f463d54e606b58fba28ab8af7989b0f1019a94e6 In msimprpl, support dynamically-allocated strings in message element names, and use them in msim_msg_dictionary_parse(). Dynamically-allocated strings were used before, but MsimMessage didn't support them, so they were leaked. This change should fix the leaks. Closes #3281. diff -r f463d54e606b -r 9479cf89a97d libpurple/protocols/myspace/message.c --- a/libpurple/protocols/myspace/message.c Mon Feb 18 19:22:39 2008 +0000 +++ b/libpurple/protocols/myspace/message.c Mon Feb 25 00:25:23 2008 +0000 @@ -429,6 +429,7 @@ * @param user_data Not used; required to match g_list_foreach() callback prototype. * * Frees both the element data and the element itself. + * Also frees the name if dynamic_name is TRUE. */ static void msim_msg_free_element(gpointer data, gpointer user_data) @@ -439,6 +440,12 @@ msim_msg_free_element_data(elem); + if (elem->dynamic_name) + /* Need to cast to remove const-ness, because + * elem->name is almost always a constant, static + * string, but not in this case. */ + g_free((gchar *)elem->name); + g_free(elem); } @@ -512,15 +519,18 @@ /** Create a new MsimMessageElement * - must be g_free()'d. * * For internal use; users probably want msim_msg_append() or msim_msg_insert_before(). + * + * @param dynamic_name Whether 'name' should be freed when the message is destroyed. */ static MsimMessageElement * -msim_msg_element_new(const gchar *name, MsimMessageType type, gpointer data) +msim_msg_element_new(const gchar *name, MsimMessageType type, gpointer data, gboolean dynamic_name) { MsimMessageElement *elem; elem = g_new0(MsimMessageElement, 1); elem->name = name; + elem->dynamic_name = dynamic_name; elem->type = type; elem->data = data; @@ -559,7 +569,18 @@ msim_msg_append(MsimMessage *msg, const gchar *name, MsimMessageType type, gpointer data) { - return g_list_append(msg, msim_msg_element_new(name, type, data)); + return g_list_append(msg, msim_msg_element_new(name, type, data, FALSE)); +} + +/** Append a new element, but with a dynamically-allocated name. + * Exactly the same as msim_msg_append(), except 'name' will be freed when + * the message is destroyed. Normally, it isn't, because a static string is given. + */ +static MsimMessage * +msim_msg_append_dynamic_name(MsimMessage *msg, gchar *name, + MsimMessageType type, gpointer data) +{ + return g_list_append(msg, msim_msg_element_new(name, type, data, TRUE)); } /** Insert a new element into a message, before the given element name. @@ -576,7 +597,7 @@ MsimMessageElement *new_elem; GList *node_before; - new_elem = msim_msg_element_new(name, type, data); + new_elem = msim_msg_element_new(name, type, data, FALSE); node_before = msim_msg_get_node(msg, name_before); @@ -1196,8 +1217,9 @@ purple_debug_info("msim_msg_parse_dictionary","-- %s: %s\n", key ? key : "(NULL)", value ? value : "(NULL)"); #endif - /* TODO: free key; right now it is treated as static */ - dict = msim_msg_append(dict, g_strdup(key), MSIM_TYPE_RAW, g_strdup(value)); + /* Append with _dynamic_name since g_strdup(key) is dynamic, and + * needs to be freed when the message is destroyed. It isn't static as usual. */ + dict = msim_msg_append_dynamic_name(dict, g_strdup(key), MSIM_TYPE_RAW, g_strdup(value)); g_strfreev(elements); } diff -r f463d54e606b -r 9479cf89a97d libpurple/protocols/myspace/message.h --- a/libpurple/protocols/myspace/message.h Mon Feb 18 19:22:39 2008 +0000 +++ b/libpurple/protocols/myspace/message.h Mon Feb 25 00:25:23 2008 +0000 @@ -29,6 +29,7 @@ typedef struct _MsimMessageElement { const gchar *name; /**< Textual name of element. */ + gboolean dynamic_name; /**< TRUE if 'name' is a dynamic string to be freed, not static. */ guint type; /**< MSIM_TYPE_* code. */ gpointer data; /**< Pointer to data, or GUINT_TO_POINTER for int/bool. */ } MsimMessageElement;