comparison 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
comparison
equal deleted inserted replaced
32497:a9f13cb4e945 32498:114a98da1a5f
19 fail_if(xmlnode_from_str(malicious_xml_doc, -1), 19 fail_if(xmlnode_from_str(malicious_xml_doc, -1),
20 "xmlnode_from_str() returned an XML tree, but we didn't want it to"); 20 "xmlnode_from_str() returned an XML tree, but we didn't want it to");
21 } 21 }
22 END_TEST 22 END_TEST
23 23
24 #define check_doc_structure(x) { \
25 xmlnode *ping, *child1, *child2; \
26 fail_if(x == NULL, "Failed to parse document"); \
27 ping = xmlnode_get_child(x, "ping"); \
28 fail_if(ping == NULL, "Failed to find 'ping' child"); \
29 child1 = xmlnode_get_child(ping, "child1"); \
30 fail_if(child1 == NULL, "Failed to find 'child1'"); \
31 child2 = xmlnode_get_child(child1, "child2"); \
32 fail_if(child2 == NULL, "Failed to find 'child2'"); \
33 xmlnode_new_child(child2, "a"); \
34 \
35 assert_string_equal("jabber:client", xmlnode_get_namespace(x)); \
36 /* NOTE: xmlnode_get_namespace() returns the namespace of the element, not the
37 * current default namespace. See http://www.w3.org/TR/xml-names/#defaulting and
38 * http://www.w3.org/TR/xml-names/#dt-defaultNS.
39 */ \
40 assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(ping)); \
41 assert_string_equal("jabber:client", xmlnode_get_namespace(child1)); \
42 assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(child2)); \
43 /*
44 * This fails (well, actually crashes [the ns is NULL]) unless
45 * xmlnode_new_child() actually sets the element namespace.
46 assert_string_equal("jabber:client", xmlnode_get_namespace(xmlnode_get_child(child2, "a")));
47 */ \
48 \
49 assert_string_equal("jabber:client", xmlnode_get_default_namespace(x)); \
50 assert_string_equal("jabber:client", xmlnode_get_default_namespace(ping)); \
51 assert_string_equal("jabber:client", xmlnode_get_default_namespace(child1)); \
52 assert_string_equal("jabber:client", xmlnode_get_default_namespace(child2)); \
53 }
54
55 START_TEST(test_xmlnode_prefixes)
56 {
57 const char *xml_doc =
58 "<iq type='get' xmlns='jabber:client' xmlns:ping='urn:xmpp:ping'>"
59 "<ping:ping>"
60 "<child1>"
61 "<ping:child2></ping:child2>" /* xmlns='jabber:child' */
62 "</child1>"
63 "</ping:ping>"
64 "</iq>";
65 char *str;
66 xmlnode *xml, *reparsed;
67
68 xml = xmlnode_from_str(xml_doc, -1);
69 check_doc_structure(xml);
70
71 /* Check that xmlnode_from_str(xmlnode_to_str(xml, NULL), -1) is idempotent. */
72 str = xmlnode_to_str(xml, NULL);
73 fail_if(str == NULL, "Failed to serialize XMLnode");
74 reparsed = xmlnode_from_str(str, -1);
75 fail_if(reparsed == NULL, "Failed to reparse xml document");
76 check_doc_structure(reparsed);
77
78 g_free(str);
79 xmlnode_free(xml);
80 xmlnode_free(reparsed);
81 }
82 END_TEST
83
24 Suite * 84 Suite *
25 xmlnode_suite(void) 85 xmlnode_suite(void)
26 { 86 {
27 Suite *s = suite_create("Utility Functions"); 87 Suite *s = suite_create("Utility Functions");
28 88
29 TCase *tc = tcase_create("xmlnode"); 89 TCase *tc = tcase_create("xmlnode");
30 tcase_add_test(tc, test_xmlnode_billion_laughs_attack); 90 tcase_add_test(tc, test_xmlnode_billion_laughs_attack);
91 tcase_add_test(tc, test_xmlnode_prefixes);
92
31 suite_add_tcase(s, tc); 93 suite_add_tcase(s, tc);
32 94
33 return s; 95 return s;
34 } 96 }