diff options
author | Joanna Hulboj <joanna.hulboj@isode.com> | 2019-09-12 08:54:19 (GMT) |
---|---|---|
committer | Joanna Hulboj <joanna.hulboj@isode.com> | 2019-09-16 08:17:07 (GMT) |
commit | 181ac4a83ba4a82be683fb0a6f08393d3c91320c (patch) | |
tree | 76e41aac0cda8be5582137d34cb0c9f5683c9dc2 | |
parent | 415870c04a7e6cabf13e6acf3a94bb0f68732907 (diff) | |
download | swift-181ac4a83ba4a82be683fb0a6f08393d3c91320c.zip swift-181ac4a83ba4a82be683fb0a6f08393d3c91320c.tar.bz2 |
Close the stream for disallowed XML features
According to RFC 6120 if any disallowed XML feature is encountered,
we should close the stream with a <restricted-xml/>. The following
features of XML are prohibited in XMPP:
- processing instructions
- internal or external DTD subsets
- internal or external entity references
- comments
Test-information:
Unit tests pass on Windows 10 and Ubuntu 18.04.1 LTS
Change-Id: I475920c91b7f9da51ab37c106a4783a52f6e3cae
-rw-r--r-- | Sluift/ElementConvertors/DOMElementConvertor.cpp | 2 | ||||
-rw-r--r-- | Swift/Controllers/Settings/XMLSettingsProvider.cpp | 2 | ||||
-rw-r--r-- | Swiften/Parser/ExpatParser.cpp | 18 | ||||
-rw-r--r-- | Swiften/Parser/ExpatParser.h | 2 | ||||
-rw-r--r-- | Swiften/Parser/LibXMLParser.cpp | 30 | ||||
-rw-r--r-- | Swiften/Parser/LibXMLParser.h | 5 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h | 2 | ||||
-rw-r--r-- | Swiften/Parser/PlatformXMLParserFactory.cpp | 6 | ||||
-rw-r--r-- | Swiften/Parser/PlatformXMLParserFactory.h | 2 | ||||
-rw-r--r-- | Swiften/Parser/UnitTest/XMLParserTest.cpp | 42 | ||||
-rw-r--r-- | Swiften/Parser/XMLParser.cpp | 2 | ||||
-rw-r--r-- | Swiften/Parser/XMLParser.h | 7 | ||||
-rw-r--r-- | Swiften/Parser/XMLParserFactory.h | 2 |
13 files changed, 105 insertions, 17 deletions
diff --git a/Sluift/ElementConvertors/DOMElementConvertor.cpp b/Sluift/ElementConvertors/DOMElementConvertor.cpp index 56b45aa..5e72cc8 100644 --- a/Sluift/ElementConvertors/DOMElementConvertor.cpp +++ b/Sluift/ElementConvertors/DOMElementConvertor.cpp @@ -187,3 +187,3 @@ boost::optional<std::string> DOMElementConvertor::convertToLua( ParserClient parserClient(L); - std::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient)); + std::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient, false)); bool result = parser->parse(serializedPayload); diff --git a/Swift/Controllers/Settings/XMLSettingsProvider.cpp b/Swift/Controllers/Settings/XMLSettingsProvider.cpp index 2573af0..8415209 100644 --- a/Swift/Controllers/Settings/XMLSettingsProvider.cpp +++ b/Swift/Controllers/Settings/XMLSettingsProvider.cpp @@ -20,3 +20,3 @@ XMLSettingsProvider::XMLSettingsProvider(const std::string& xmlConfig) : level_( PlatformXMLParserFactory factory; - auto parser = factory.createXMLParser(this); + auto parser = factory.createXMLParser(this, true); if (parser->parse(xmlConfig)) { diff --git a/Swiften/Parser/ExpatParser.cpp b/Swiften/Parser/ExpatParser.cpp index a50949b..640d561 100644 --- a/Swiften/Parser/ExpatParser.cpp +++ b/Swiften/Parser/ExpatParser.cpp @@ -74,4 +74,17 @@ static void handleEntityDeclaration(void* parser, const XML_Char*, int, const XM +static void handleComment(void* parser, const XML_Char* /*data*/) { + if (!static_cast<ExpatParser*>(parser)->allowsComments()) { + static_cast<ExpatParser*>(parser)->stopParser(); + } +} + +static void handleProcessingInstruction(void* parser, const XML_Char* /*target*/, const XML_Char* /*data*/) { + static_cast<ExpatParser*>(parser)->stopParser(); +} + +static void handleDoctypeDeclaration(void* parser, const XML_Char* /*doctypeName*/, const XML_Char* /*sysid*/, const XML_Char* /*pubid*/, int /*has_internal_subset*/) { + static_cast<ExpatParser*>(parser)->stopParser(); +} -ExpatParser::ExpatParser(XMLParserClient* client) : XMLParser(client), p(new Private()) { +ExpatParser::ExpatParser(XMLParserClient* client, bool allowComments) : XMLParser(client, allowComments), p(new Private()) { p->parser_ = XML_ParserCreateNS("UTF-8", NAMESPACE_SEPARATOR); @@ -83,2 +96,5 @@ ExpatParser::ExpatParser(XMLParserClient* client) : XMLParser(client), p(new Pri XML_SetNamespaceDeclHandler(p->parser_, handleNamespaceDeclaration, nullptr); + XML_SetCommentHandler(p->parser_, handleComment); + XML_SetProcessingInstructionHandler(p->parser_, handleProcessingInstruction); + XML_SetDoctypeDeclHandler(p->parser_, handleDoctypeDeclaration, nullptr); } diff --git a/Swiften/Parser/ExpatParser.h b/Swiften/Parser/ExpatParser.h index 7583339..34d790d 100644 --- a/Swiften/Parser/ExpatParser.h +++ b/Swiften/Parser/ExpatParser.h @@ -18,3 +18,3 @@ namespace Swift { public: - ExpatParser(XMLParserClient* client); + ExpatParser(XMLParserClient* client, bool allowComments = false); ~ExpatParser(); diff --git a/Swiften/Parser/LibXMLParser.cpp b/Swiften/Parser/LibXMLParser.cpp index 192f44b..4e02059 100644 --- a/Swiften/Parser/LibXMLParser.cpp +++ b/Swiften/Parser/LibXMLParser.cpp @@ -61,2 +61,20 @@ static void handleCharacterData(void* parser, const xmlChar* data, int len) { +static void handleComment(void* parser, const xmlChar* /*data*/) { + if (!static_cast<LibXMLParser*>(parser)->allowsComments()) { + static_cast<LibXMLParser*>(parser)->stopParser(); + } +} + +static void handleEntityDeclaration(void * parser, const xmlChar* /*name*/, int /*type*/, const xmlChar* /*publicId*/, const xmlChar* /*systemId*/, xmlChar* /*content*/) { + static_cast<LibXMLParser*>(parser)->stopParser(); +} + +static void handleProcessingInstruction(void* parser, const xmlChar* /*target*/, const xmlChar* /*data*/) { + static_cast<LibXMLParser*>(parser)->stopParser(); +} + +static void handleExternalSubset(void* parser, const xmlChar * /*name*/, const xmlChar * /*ExternalID*/, const xmlChar * /*SystemID*/) { + static_cast<LibXMLParser*>(parser)->stopParser(); +} + static void handleError(void*, const char* /*m*/, ... ) { @@ -75,3 +93,3 @@ bool LibXMLParser::initialized = false; -LibXMLParser::LibXMLParser(XMLParserClient* client) : XMLParser(client), p(new Private()) { +LibXMLParser::LibXMLParser(XMLParserClient* client, bool allowComments) : XMLParser(client, allowComments), p(new Private()) { // Initialize libXML for multithreaded applications @@ -89,2 +107,6 @@ LibXMLParser::LibXMLParser(XMLParserClient* client) : XMLParser(client), p(new P p->handler_.error = &handleError; + p->handler_.comment = &handleComment; + p->handler_.entityDecl = &handleEntityDeclaration; + p->handler_.processingInstruction = &handleProcessingInstruction; + p->handler_.externalSubset = &handleExternalSubset; @@ -108,2 +130,3 @@ bool LibXMLParser::parse(const std::string& data, bool finalData) { } + if (stopped_) return false; xmlError* error = xmlCtxtGetLastError(p->context_); @@ -117,2 +140,7 @@ bool LibXMLParser::parse(const std::string& data, bool finalData) { +void LibXMLParser::stopParser() { + stopped_ = true; + xmlStopParser(p->context_); +} + } diff --git a/Swiften/Parser/LibXMLParser.h b/Swiften/Parser/LibXMLParser.h index a863867..e21770d 100644 --- a/Swiften/Parser/LibXMLParser.h +++ b/Swiften/Parser/LibXMLParser.h @@ -21,3 +21,3 @@ namespace Swift { public: - LibXMLParser(XMLParserClient* client); + LibXMLParser(XMLParserClient* client, bool allowComments = false); virtual ~LibXMLParser(); @@ -26,4 +26,7 @@ namespace Swift { + void stopParser(); + private: static bool initialized; + bool stopped_ = false; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h b/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h index dcdbffa..8f9e0e1 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h +++ b/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h @@ -21,3 +21,3 @@ namespace Swift { PayloadsParserTester() : level(0) { - xmlParser = PlatformXMLParserFactory().createXMLParser(this); + xmlParser = PlatformXMLParserFactory().createXMLParser(this, false); } diff --git a/Swiften/Parser/PlatformXMLParserFactory.cpp b/Swiften/Parser/PlatformXMLParserFactory.cpp index bf66734..a424aca 100644 --- a/Swiften/Parser/PlatformXMLParserFactory.cpp +++ b/Swiften/Parser/PlatformXMLParserFactory.cpp @@ -22,7 +22,7 @@ PlatformXMLParserFactory::PlatformXMLParserFactory() { -std::unique_ptr<XMLParser> PlatformXMLParserFactory::createXMLParser(XMLParserClient* client) { +std::unique_ptr<XMLParser> PlatformXMLParserFactory::createXMLParser(XMLParserClient* client, bool allowComments) { #ifdef HAVE_LIBXML - return std::make_unique<LibXMLParser>(client); + return std::make_unique<LibXMLParser>(client, allowComments); #else - return std::make_unique<ExpatParser>(client); + return std::make_unique<ExpatParser>(client, allowComments); #endif diff --git a/Swiften/Parser/PlatformXMLParserFactory.h b/Swiften/Parser/PlatformXMLParserFactory.h index fa3ca19..d72a513 100644 --- a/Swiften/Parser/PlatformXMLParserFactory.h +++ b/Swiften/Parser/PlatformXMLParserFactory.h @@ -16,3 +16,3 @@ namespace Swift { - virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*); + virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*, bool allowComments = false); }; diff --git a/Swiften/Parser/UnitTest/XMLParserTest.cpp b/Swiften/Parser/UnitTest/XMLParserTest.cpp index c026b4b..63d30ea 100644 --- a/Swiften/Parser/UnitTest/XMLParserTest.cpp +++ b/Swiften/Parser/UnitTest/XMLParserTest.cpp @@ -41,2 +41,6 @@ class XMLParserTest : public CppUnit::TestFixture { //CPPUNIT_TEST(testParse_UndefinedAttributePrefix); + CPPUNIT_TEST(testParse_AllowCommentsInXML); + CPPUNIT_TEST(testParse_DisallowCommentsInXML); + CPPUNIT_TEST(testParse_Doctype); + CPPUNIT_TEST(testParse_ProcessingInstructions); CPPUNIT_TEST_SUITE_END(); @@ -187,3 +191,3 @@ class XMLParserTest : public CppUnit::TestFixture { void testParse_UnhandledXML() { - ParserType testling(&client_); + ParserType testling(&client_, true); @@ -333,4 +337,3 @@ class XMLParserTest : public CppUnit::TestFixture { - CPPUNIT_ASSERT(testling.parse( - "<foo bar:baz='bla'/>")); + CPPUNIT_ASSERT(testling.parse("<foo bar:baz='bla'/>")); @@ -340,2 +343,34 @@ class XMLParserTest : public CppUnit::TestFixture { + void testParse_AllowCommentsInXML() { + ParserType testling(&client_, true); + + CPPUNIT_ASSERT(testling.parse("<message><!-- Some More Comments Testing --></message>")); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), client_.events.size()); + + CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); + CPPUNIT_ASSERT_EQUAL(std::string("message"), client_.events[0].data); + + CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[1].type); + CPPUNIT_ASSERT_EQUAL(std::string("message"), client_.events[1].data); + } + + void testParse_DisallowCommentsInXML() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(!testling.parse("<message><!-- Some More Comments Testing --></message>")); + } + + void testParse_Doctype() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(!testling.parse("<!DOCTYPE greeting SYSTEM \"hello.dtd\">")); + } + + void testParse_ProcessingInstructions() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(!testling.parse("<?xml-stylesheet type=\"text/xsl\" href=\"Sample.xsl\"?>")); + } + private: @@ -380,2 +415,3 @@ class XMLParserTest : public CppUnit::TestFixture { } + std::vector<Event> events; diff --git a/Swiften/Parser/XMLParser.cpp b/Swiften/Parser/XMLParser.cpp index 8e92fe4..8a0799f 100644 --- a/Swiften/Parser/XMLParser.cpp +++ b/Swiften/Parser/XMLParser.cpp @@ -10,3 +10,3 @@ namespace Swift { -XMLParser::XMLParser(XMLParserClient* client) : client_(client) { +XMLParser::XMLParser(XMLParserClient* client, bool allowComments) : client_(client), allowComments_(allowComments){ } diff --git a/Swiften/Parser/XMLParser.h b/Swiften/Parser/XMLParser.h index ad79b2d..3b09d22 100644 --- a/Swiften/Parser/XMLParser.h +++ b/Swiften/Parser/XMLParser.h @@ -17,3 +17,3 @@ namespace Swift { public: - XMLParser(XMLParserClient* client); + XMLParser(XMLParserClient* client, bool allowComments = false); virtual ~XMLParser(); @@ -26,4 +26,9 @@ namespace Swift { + bool allowsComments() const { + return allowComments_; + } + private: XMLParserClient* client_; + const bool allowComments_ = false; }; diff --git a/Swiften/Parser/XMLParserFactory.h b/Swiften/Parser/XMLParserFactory.h index 595512b..ae3c90e 100644 --- a/Swiften/Parser/XMLParserFactory.h +++ b/Swiften/Parser/XMLParserFactory.h @@ -20,3 +20,3 @@ namespace Swift { - virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*) = 0; + virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*, bool allowComments = false) = 0; }; |