# HG changeset patch # User Mark Doliner # Date 1290422746 0 # Node ID 61d160a4689f605cbe6fd7aed3a3daa038abc0e1 # Parent 6f9a43a2b716772e342e58fac0bbc1c4a0cf8bda 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. diff -r 6f9a43a2b716 -r 61d160a4689f libpurple/protocols/oscar/oscar.c --- 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); } diff -r 6f9a43a2b716 -r 61d160a4689f libpurple/xmlnode.c --- 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);