* Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * If we really wanted to test the billion laughs attack we would * need to have more than just 4 ha's. But as long as this shorter * document fails to parse, the longer one should also fail to parse. test_xmlnode_billion_laughs_attack(void) { const char *malicious_xml_doc = "<!DOCTYPE root [ <!ENTITY ha \"Ha !\"><!ENTITY ha2 \"&ha; &ha;\"><!ENTITY ha3 \"&ha2; &ha2;\"> ]><root>&ha3;</root>"; /* Uncomment this line if you want to see the error message given by the parser for the above XML document */ /* purple_debug_set_enabled(TRUE); */ g_assert_null(purple_xmlnode_from_str(malicious_xml_doc, -1)); #define check_doc_structure(x) { \ PurpleXmlNode *ping, *child1, *child2; \ ping = purple_xmlnode_get_child(x, "ping"); \ g_assert_nonnull(ping); \ child1 = purple_xmlnode_get_child(ping, "child1"); \ g_assert_nonnull(child1); \ child2 = purple_xmlnode_get_child(child1, "child2"); \ g_assert_nonnull(child2); \ purple_xmlnode_new_child(child2, "a"); \ g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_namespace(x)); \ /* NOTE: purple_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. g_assert_cmpstr("urn:xmpp:ping", ==, purple_xmlnode_get_namespace(ping)); \ g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_namespace(child1)); \ g_assert_cmpstr("urn:xmpp:ping", ==, purple_xmlnode_get_namespace(child2)); \ * This fails (well, actually crashes [the ns is NULL]) unless * purple_xmlnode_new_child() actually sets the element namespace. g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_namespace(purple_xmlnode_get_child(child2, "a"))); g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_default_namespace(x)); \ g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_default_namespace(ping)); \ g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_default_namespace(child1)); \ g_assert_cmpstr("jabber:client", ==, purple_xmlnode_get_default_namespace(child2)); \ test_xmlnode_prefixes(void) { "<iq type='get' xmlns='jabber:client' xmlns:ping='urn:xmpp:ping'>" "<ping:child2></ping:child2>" /* xmlns='jabber:child' */ PurpleXmlNode *xml, *reparsed; xml = purple_xmlnode_from_str(xml_doc, -1); check_doc_structure(xml); /* Check that purple_xmlnode_from_str(purple_xmlnode_to_str(xml, NULL), -1) is idempotent. */ str = purple_xmlnode_to_str(xml, NULL); reparsed = purple_xmlnode_from_str(str, -1); g_assert_nonnull(reparsed); check_doc_structure(reparsed); purple_xmlnode_free(xml); purple_xmlnode_free(reparsed); test_strip_prefixes(void) { const char *xml_doc = "<message xmlns='jabber:client' from='user@gmail.com/resource' to='another_user@darkrain42.org' type='chat' id='purple'>" "<cha:active xmlns:cha='http://jabber.org/protocol/chatstates'/>" "<im:html xmlns:im='http://jabber.org/protocol/xhtml-im'>" "<xht:body xmlns:xht='http://www.w3.org/1999/xhtml'>" "<xht:p>xvlc <xht:span style='font-weight: bold;'>xvlc</xht:span></xht:p>" const char *out = "<message xmlns='jabber:client' from='user@gmail.com/resource' to='another_user@darkrain42.org' type='chat' id='purple'>" "<active xmlns:cha='http://jabber.org/protocol/chatstates' xmlns='http://jabber.org/protocol/chatstates'/>" "<html xmlns:im='http://jabber.org/protocol/xhtml-im' xmlns='http://jabber.org/protocol/xhtml-im'>" "<body xmlns:xht='http://www.w3.org/1999/xhtml' xmlns='http://www.w3.org/1999/xhtml'>" "<p>xvlc <span style='font-weight: bold;'>xvlc</span></p>" xml = purple_xmlnode_from_str(xml_doc, -1); purple_xmlnode_strip_prefixes(xml); str = purple_xmlnode_to_str(xml, NULL); g_assert_cmpstr(out, ==, str); purple_xmlnode_free(xml); main(gint argc, gchar **argv) { g_test_init(&argc, &argv, NULL); g_test_add_func("/xmlnode/billion_laughs_attack", test_xmlnode_billion_laughs_attack); g_test_add_func("/xmlnode/prefixes", g_test_add_func("/xmlnode/strip_prefixes",