From 02c18de062510e8061598bf492c68cb5b0624831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Tue, 24 Apr 2012 20:22:30 +0200 Subject: Make built-in expat ignore unbound prefix namespaces. This works around a problem with broken servers relaying illegal stanzas from broken clients. Obviously only works when using the bundled Expat. Note that the system OS X libXML also seems to behave this way. diff --git a/3rdParty/Expat/ignore_unbound_prefix_namespaces.diff b/3rdParty/Expat/ignore_unbound_prefix_namespaces.diff new file mode 100644 index 0000000..945e436 --- /dev/null +++ b/3rdParty/Expat/ignore_unbound_prefix_namespaces.diff @@ -0,0 +1,56 @@ +diff --git a/3rdParty/Expat/src/xmlparse.c b/3rdParty/Expat/src/xmlparse.c +index 94e31de..ad5add2 100755 +--- a/src/xmlparse.c ++++ b/src/xmlparse.c +@@ -2808,8 +2808,10 @@ storeAtts(XML_Parser parser, const ENCODING *enc, + ((XML_Char *)s)[-1] = 0; /* clear flag */ + id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0); + b = id->prefix->binding; +- if (!b) +- return XML_ERROR_UNBOUND_PREFIX; ++ if (!b) { ++ //return XML_ERROR_UNBOUND_PREFIX; ++ continue; ++ } + + /* as we expand the name we also calculate its hash value */ + for (j = 0; j < b->uriLen; j++) { +@@ -2887,7 +2889,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, + return XML_ERROR_NONE; + + /* expand the element type name */ +- if (elementType->prefix) { ++ if (elementType->prefix && elementType->prefix->binding) { + binding = elementType->prefix->binding; + if (!binding) + return XML_ERROR_UNBOUND_PREFIX; +@@ -2983,10 +2985,10 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, + && prefix->name[2] == XML_T(ASCII_l)) { + + /* Not allowed to bind xmlns */ +- if (prefix->name[3] == XML_T(ASCII_n) ++ /*if (prefix->name[3] == XML_T(ASCII_n) + && prefix->name[4] == XML_T(ASCII_s) + && prefix->name[5] == XML_T('\0')) +- return XML_ERROR_RESERVED_PREFIX_XMLNS; ++ return XML_ERROR_RESERVED_PREFIX_XMLNS;*/ + + if (prefix->name[3] == XML_T('\0')) + mustBeXML = XML_TRUE; +@@ -3003,12 +3005,12 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, + isXML = isXML && len == xmlLen; + isXMLNS = isXMLNS && len == xmlnsLen; + +- if (mustBeXML != isXML) ++ /*if (mustBeXML != isXML) + return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML +- : XML_ERROR_RESERVED_NAMESPACE_URI; ++ : XML_ERROR_RESERVED_NAMESPACE_URI;*/ + +- if (isXMLNS) +- return XML_ERROR_RESERVED_NAMESPACE_URI; ++ /*if (isXMLNS) ++ return XML_ERROR_RESERVED_NAMESPACE_URI;*/ + + if (namespaceSeparator) + len++; diff --git a/3rdParty/Expat/src/xmlparse.c b/3rdParty/Expat/src/xmlparse.c index 94e31de..ad5add2 100755 --- a/3rdParty/Expat/src/xmlparse.c +++ b/3rdParty/Expat/src/xmlparse.c @@ -2808,8 +2808,10 @@ storeAtts(XML_Parser parser, const ENCODING *enc, ((XML_Char *)s)[-1] = 0; /* clear flag */ id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0); b = id->prefix->binding; - if (!b) - return XML_ERROR_UNBOUND_PREFIX; + if (!b) { + //return XML_ERROR_UNBOUND_PREFIX; + continue; + } /* as we expand the name we also calculate its hash value */ for (j = 0; j < b->uriLen; j++) { @@ -2887,7 +2889,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, return XML_ERROR_NONE; /* expand the element type name */ - if (elementType->prefix) { + if (elementType->prefix && elementType->prefix->binding) { binding = elementType->prefix->binding; if (!binding) return XML_ERROR_UNBOUND_PREFIX; @@ -2983,10 +2985,10 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, && prefix->name[2] == XML_T(ASCII_l)) { /* Not allowed to bind xmlns */ - if (prefix->name[3] == XML_T(ASCII_n) + /*if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s) && prefix->name[5] == XML_T('\0')) - return XML_ERROR_RESERVED_PREFIX_XMLNS; + return XML_ERROR_RESERVED_PREFIX_XMLNS;*/ if (prefix->name[3] == XML_T('\0')) mustBeXML = XML_TRUE; @@ -3003,12 +3005,12 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, isXML = isXML && len == xmlLen; isXMLNS = isXMLNS && len == xmlnsLen; - if (mustBeXML != isXML) + /*if (mustBeXML != isXML) return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML - : XML_ERROR_RESERVED_NAMESPACE_URI; + : XML_ERROR_RESERVED_NAMESPACE_URI;*/ - if (isXMLNS) - return XML_ERROR_RESERVED_NAMESPACE_URI; + /*if (isXMLNS) + return XML_ERROR_RESERVED_NAMESPACE_URI;*/ if (namespaceSeparator) len++; diff --git a/Swiften/Parser/UnitTest/XMLParserTest.cpp b/Swiften/Parser/UnitTest/XMLParserTest.cpp index 8ff56c0..3c84220 100644 --- a/Swiften/Parser/UnitTest/XMLParserTest.cpp +++ b/Swiften/Parser/UnitTest/XMLParserTest.cpp @@ -35,6 +35,8 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testParse_AttributeWithoutNamespace); CPPUNIT_TEST(testParse_AttributeWithNamespace); CPPUNIT_TEST(testParse_BillionLaughs); + //CPPUNIT_TEST(testParse_UndefinedPrefix); + //CPPUNIT_TEST(testParse_UndefinedAttributePrefix); CPPUNIT_TEST_SUITE_END(); public: @@ -271,6 +273,41 @@ class XMLParserTest : public CppUnit::TestFixture { "&lol9;" )); } + + void testParse_UndefinedPrefix() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(testling.parse( + "")); + + CPPUNIT_ASSERT_EQUAL(static_cast(4), client_.events.size()); + + CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); + CPPUNIT_ASSERT_EQUAL(std::string("foo:bar"), client_.events[0].data); + CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[0].ns); + + CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); + CPPUNIT_ASSERT_EQUAL(std::string("bla"), client_.events[1].data); + CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[1].ns); + + CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[2].type); + CPPUNIT_ASSERT_EQUAL(std::string("bla"), client_.events[2].data); + CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[2].ns); + + CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[3].type); + CPPUNIT_ASSERT_EQUAL(std::string("foo:bar"), client_.events[3].data); + CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[3].ns); + } + + void testParse_UndefinedAttributePrefix() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(testling.parse( + "")); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), client_.events[0].attributes.getEntries().size()); + CPPUNIT_ASSERT_EQUAL(std::string("bar:baz"), client_.events[0].attributes.getEntries()[0].getAttribute().getName()); + } private: class Client : public XMLParserClient { -- cgit v0.10.2-6-g49f6