4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 #include "../xmlnode.h"
28 * If we really wanted to test the billion laughs attack we would
29 * need to have more than just 4 ha's. But as long as this shorter
30 * document fails to parse, the longer one should also fail to parse.
33 test_xmlnode_billion_laughs_attack(void) {
34 const char *malicious_xml_doc
= "<!DOCTYPE root [ <!ENTITY ha \"Ha !\"><!ENTITY ha2 \"&ha; &ha;\"><!ENTITY ha3 \"&ha2; &ha2;\"> ]><root>&ha3;</root>";
36 /* Uncomment this line if you want to see the error message given by
37 the parser for the above XML document */
38 /* purple_debug_set_enabled(TRUE); */
40 g_assert_null(purple_xmlnode_from_str(malicious_xml_doc
, -1));
43 #define check_doc_structure(x) { \
44 PurpleXmlNode *ping, *child1, *child2; \
45 g_assert_nonnull(x); \
46 ping = purple_xmlnode_get_child(x, "ping"); \
47 g_assert_nonnull(ping); \
48 child1 = purple_xmlnode_get_child(ping, "child1"); \
49 g_assert_nonnull(child1); \
50 child2 = purple_xmlnode_get_child(child1, "child2"); \
51 g_assert_nonnull(child2); \
52 purple_xmlnode_new_child(child2, "a"); \
54 g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_namespace(x)); \
55 /* NOTE: purple_xmlnode_get_namespace() returns the namespace of the element, not the
56 * current default namespace. See http://www.w3.org/TR/xml-names/#defaulting and
57 * http://www.w3.org/TR/xml-names/#dt-defaultNS.
59 g_assert_cmpstr("urn:xmpp:ping", ==, purple_xmlnode_get_namespace(ping)); \
60 g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_namespace(child1)); \
61 g_assert_cmpstr("urn:xmpp:ping", ==, purple_xmlnode_get_namespace(child2)); \
63 * This fails (well, actually crashes [the ns is NULL]) unless
64 * purple_xmlnode_new_child() actually sets the element namespace.
65 g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_namespace(purple_xmlnode_get_child(child2, "a")));
68 g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_default_namespace(x)); \
69 g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_default_namespace(ping)); \
70 g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_default_namespace(child1)); \
71 g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_default_namespace(child2)); \
75 test_xmlnode_prefixes(void) {
77 "<iq type='get' xmlns='jabber:client' xmlns:ping='urn:xmpp:ping'>"
80 "<ping:child2></ping:child2>" /* xmlns='jabber:child' */
85 PurpleXmlNode
*xml
, *reparsed
;
87 xml
= purple_xmlnode_from_str(xml_doc
, -1);
88 check_doc_structure(xml
);
90 /* Check that purple_xmlnode_from_str(purple_xmlnode_to_str(xml, NULL), -1) is idempotent. */
91 str
= purple_xmlnode_to_str(xml
, NULL
);
92 g_assert_nonnull(str
);
93 reparsed
= purple_xmlnode_from_str(str
, -1);
94 g_assert_nonnull(reparsed
);
95 check_doc_structure(reparsed
);
98 purple_xmlnode_free(xml
);
99 purple_xmlnode_free(reparsed
);
103 test_strip_prefixes(void) {
104 const char *xml_doc
= "<message xmlns='jabber:client' from='user@gmail.com/resource' to='another_user@darkrain42.org' type='chat' id='purple'>"
105 "<cha:active xmlns:cha='http://jabber.org/protocol/chatstates'/>"
106 "<body>xvlc xvlc</body>"
107 "<im:html xmlns:im='http://jabber.org/protocol/xhtml-im'>"
108 "<xht:body xmlns:xht='http://www.w3.org/1999/xhtml'>"
109 "<xht:p>xvlc <xht:span style='font-weight: bold;'>xvlc</xht:span></xht:p>"
113 const char *out
= "<message xmlns='jabber:client' from='user@gmail.com/resource' to='another_user@darkrain42.org' type='chat' id='purple'>"
114 "<active xmlns:cha='http://jabber.org/protocol/chatstates' xmlns='http://jabber.org/protocol/chatstates'/>"
115 "<body>xvlc xvlc</body>"
116 "<html xmlns:im='http://jabber.org/protocol/xhtml-im' xmlns='http://jabber.org/protocol/xhtml-im'>"
117 "<body xmlns:xht='http://www.w3.org/1999/xhtml' xmlns='http://www.w3.org/1999/xhtml'>"
118 "<p>xvlc <span style='font-weight: bold;'>xvlc</span></p>"
125 xml
= purple_xmlnode_from_str(xml_doc
, -1);
126 g_assert_nonnull(xml
);
128 purple_xmlnode_strip_prefixes(xml
);
129 str
= purple_xmlnode_to_str(xml
, NULL
);
130 g_assert_cmpstr(out
, ==, str
);
133 purple_xmlnode_free(xml
);
137 main(gint argc
, gchar
**argv
) {
138 g_test_init(&argc
, &argv
, NULL
);
140 g_test_add_func("/xmlnode/billion_laughs_attack",
141 test_xmlnode_billion_laughs_attack
);
142 g_test_add_func("/xmlnode/prefixes",
143 test_xmlnode_prefixes
);
144 g_test_add_func("/xmlnode/strip_prefixes",
145 test_strip_prefixes
);