changeset 31397:61d160a4689f

Move the call to flap_connection_schedule_destroy from oscar_chat_kill to oscar_chat_leave. This avoids having flap_connection_schedule_destroy called from purple_connerr, which itself is called by flap_connection_destroy_cb I'm hoping this change fixes #5927, the oscar crash when a flap connection is disconnected.
author Mark Doliner <mark@kingant.net>
date Mon, 22 Nov 2010 10:45:46 +0000
parents 6f9a43a2b716
children 3cf95447b26c
files libpurple/protocols/oscar/oscar.c libpurple/xmlnode.c
diffstat 2 files changed, 42 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/oscar.c	Mon Nov 22 09:54:54 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Mon Nov 22 10:45:46 2010 +0000
@@ -283,7 +283,6 @@
 
 	/* Destroy the chat_connection */
 	od->oscar_chats = g_slist_remove(od->oscar_chats, cc);
-	flap_connection_schedule_destroy(cc->conn, OSCAR_DISCONNECT_DONE, NULL);
 	oscar_chat_destroy(cc);
 }
 
@@ -4451,6 +4450,7 @@
 			purple_conversation_get_name(conv));
 
 	cc = find_oscar_chat(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)));
+	flap_connection_schedule_destroy(cc->conn, OSCAR_DISCONNECT_DONE, NULL);
 	oscar_chat_kill(gc, cc);
 }
 
--- a/libpurple/xmlnode.c	Mon Nov 22 09:54:54 2010 +0000
+++ b/libpurple/xmlnode.c	Mon Nov 22 10:45:46 2010 +0000
@@ -46,6 +46,30 @@
 # define NEWLINE_S "\n"
 #endif
 
+#ifdef CHECKING_XML_STRINGS_FOR_VALID_CHARACTERS
+/*
+ * The purpose of this function is to prevent us from creating XML documents
+ * that contain characters that are not allowed in XML 1.0.  However, this
+ * change is unfortunately REALLY slow.
+ */
+static gboolean is_valid_xml10(const char *str)
+{
+	gunichar ch;
+
+	for (ch = g_utf8_get_char(str); str[0] != '\0'; str = g_utf8_next_char(str))
+	{
+		/*
+		 * Valid characters in XML 1.0 are: #x9 #xA #xD
+		 * [#x20-#xD7FF] [#xE000-#xFFFD] [#x10000-#x10FFFF]
+		 */
+		if (ch < 0x09 || (ch > 0x0a && ch < 0x0d) || (ch > 0x0d && ch < 0x20))
+			return FALSE;
+	}
+
+	return TRUE;
+}
+#endif /* CHECKING_XML_STRINGS_FOR_VALID_CHARACTERS */
+
 static xmlnode*
 new_node(const char *name, XMLNodeType type)
 {
@@ -109,6 +133,10 @@
 	g_return_if_fail(data != NULL);
 	g_return_if_fail(size != 0);
 
+#ifdef CHECKING_XML_STRINGS_FOR_VALID_CHARACTERS
+	g_return_if_fail(is_valid_xml10(data));
+#endif /* CHECKING_XML_STRINGS_FOR_VALID_CHARACTERS */
+
 	real_size = size == -1 ? strlen(data) : size;
 
 	child = new_node(NULL, XMLNODE_TYPE_DATA);
@@ -186,6 +214,11 @@
 void
 xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value)
 {
+#ifdef CHECKING_XML_STRINGS_FOR_VALID_CHARACTERS
+	g_return_if_fail(is_valid_xml10(attr));
+	g_return_if_fail(is_valid_xml10(value));
+#endif /* CHECKING_XML_STRINGS_FOR_VALID_CHARACTERS */
+
 	xmlnode_remove_attrib(node, attr);
 	xmlnode_set_attrib_full(node, attr, NULL, NULL, value);
 }
@@ -210,6 +243,14 @@
 	g_return_if_fail(node != NULL);
 	g_return_if_fail(attr != NULL);
 	g_return_if_fail(value != NULL);
+#ifdef CHECKING_XML_STRINGS_FOR_VALID_CHARACTERS
+	g_return_if_fail(is_valid_xml10(attr));
+	if (xmlns != NULL)
+		g_return_if_fail(is_valid_xml10(xmlns));
+	if (prefix != NULL)
+		g_return_if_fail(is_valid_xml10(prefix));
+	g_return_if_fail(is_valid_xml10(value));
+#endif /* CHECKING_XML_STRINGS_FOR_VALID_CHARACTERS */
 
 	xmlnode_remove_attrib_with_namespace(node, attr, xmlns);
 	attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB);