changeset 22334:9479cf89a97d

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.
author Jeffrey Connelly <jaconnel@calpoly.edu>
date Mon, 25 Feb 2008 00:25:23 +0000
parents f463d54e606b
children 9d02eb04f406
files libpurple/protocols/myspace/message.c libpurple/protocols/myspace/message.h
diffstat 2 files changed, 28 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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);
 	}
--- 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;