Mercurial > pidgin.yaz
diff libpurple/tests/test_xmlnode.c @ 32498:114a98da1a5f
xmlnode: Fix some brokeness in xmlnode serialization with prefixed elements.
Basically we were treating node->xmlns as the default namespace, but
that isn't the case with prefexed elements. In our serialization,
I believe we were adding an extraneous xmlns='' to a prefixed element,
which changes the (default) namespace for its children. (It's been
a bit too long with this in my tree, so I've forgotten the exact details)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 04 Sep 2011 18:52:18 +0000 |
parents | c8f91310bfbf |
children | 8d3b5853b017 |
line wrap: on
line diff
--- a/libpurple/tests/test_xmlnode.c Sun Sep 04 18:45:51 2011 +0000 +++ b/libpurple/tests/test_xmlnode.c Sun Sep 04 18:52:18 2011 +0000 @@ -21,6 +21,66 @@ } END_TEST +#define check_doc_structure(x) { \ + xmlnode *ping, *child1, *child2; \ + fail_if(x == NULL, "Failed to parse document"); \ + ping = xmlnode_get_child(x, "ping"); \ + fail_if(ping == NULL, "Failed to find 'ping' child"); \ + child1 = xmlnode_get_child(ping, "child1"); \ + fail_if(child1 == NULL, "Failed to find 'child1'"); \ + child2 = xmlnode_get_child(child1, "child2"); \ + fail_if(child2 == NULL, "Failed to find 'child2'"); \ + xmlnode_new_child(child2, "a"); \ + \ + assert_string_equal("jabber:client", xmlnode_get_namespace(x)); \ + /* NOTE: xmlnode_get_namespace() returns the namespace of the element, not the + * current default namespace. See http://www.w3.org/TR/xml-names/#defaulting and + * http://www.w3.org/TR/xml-names/#dt-defaultNS. + */ \ + assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(ping)); \ + assert_string_equal("jabber:client", xmlnode_get_namespace(child1)); \ + assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(child2)); \ + /* + * This fails (well, actually crashes [the ns is NULL]) unless + * xmlnode_new_child() actually sets the element namespace. + assert_string_equal("jabber:client", xmlnode_get_namespace(xmlnode_get_child(child2, "a"))); + */ \ + \ + assert_string_equal("jabber:client", xmlnode_get_default_namespace(x)); \ + assert_string_equal("jabber:client", xmlnode_get_default_namespace(ping)); \ + assert_string_equal("jabber:client", xmlnode_get_default_namespace(child1)); \ + assert_string_equal("jabber:client", xmlnode_get_default_namespace(child2)); \ +} + +START_TEST(test_xmlnode_prefixes) +{ + const char *xml_doc = + "<iq type='get' xmlns='jabber:client' xmlns:ping='urn:xmpp:ping'>" + "<ping:ping>" + "<child1>" + "<ping:child2></ping:child2>" /* xmlns='jabber:child' */ + "</child1>" + "</ping:ping>" + "</iq>"; + char *str; + xmlnode *xml, *reparsed; + + xml = xmlnode_from_str(xml_doc, -1); + check_doc_structure(xml); + + /* Check that xmlnode_from_str(xmlnode_to_str(xml, NULL), -1) is idempotent. */ + str = xmlnode_to_str(xml, NULL); + fail_if(str == NULL, "Failed to serialize XMLnode"); + reparsed = xmlnode_from_str(str, -1); + fail_if(reparsed == NULL, "Failed to reparse xml document"); + check_doc_structure(reparsed); + + g_free(str); + xmlnode_free(xml); + xmlnode_free(reparsed); +} +END_TEST + Suite * xmlnode_suite(void) { @@ -28,6 +88,8 @@ TCase *tc = tcase_create("xmlnode"); tcase_add_test(tc, test_xmlnode_billion_laughs_attack); + tcase_add_test(tc, test_xmlnode_prefixes); + suite_add_tcase(s, tc); return s;