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 | |||
| @@ -185,7 +185,7 @@ boost::optional<std::string> DOMElementConvertor::convertToLua( | |||
| 185 | 185 | ||
| 186 | // Parse the payload again | 186 | // Parse the payload again |
| 187 | ParserClient parserClient(L); | 187 | ParserClient parserClient(L); |
| 188 | std::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient)); | 188 | std::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient, false)); |
| 189 | bool result = parser->parse(serializedPayload); | 189 | bool result = parser->parse(serializedPayload); |
| 190 | assert(result); | 190 | assert(result); |
| 191 | 191 | ||
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 | |||
| @@ -18,7 +18,7 @@ namespace Swift { | |||
| 18 | XMLSettingsProvider::XMLSettingsProvider(const std::string& xmlConfig) : level_(0) { | 18 | XMLSettingsProvider::XMLSettingsProvider(const std::string& xmlConfig) : level_(0) { |
| 19 | if (!xmlConfig.empty()) { | 19 | if (!xmlConfig.empty()) { |
| 20 | PlatformXMLParserFactory factory; | 20 | PlatformXMLParserFactory factory; |
| 21 | auto parser = factory.createXMLParser(this); | 21 | auto parser = factory.createXMLParser(this, true); |
| 22 | if (parser->parse(xmlConfig)) { | 22 | if (parser->parse(xmlConfig)) { |
| 23 | SWIFT_LOG(debug) << "Found and parsed system config" << std::endl; | 23 | SWIFT_LOG(debug) << "Found and parsed system config" << std::endl; |
| 24 | } | 24 | } |
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 | |||
| @@ -72,8 +72,21 @@ static void handleEntityDeclaration(void* parser, const XML_Char*, int, const XM | |||
| 72 | static_cast<ExpatParser*>(parser)->stopParser(); | 72 | static_cast<ExpatParser*>(parser)->stopParser(); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static void handleComment(void* parser, const XML_Char* /*data*/) { | ||
| 76 | if (!static_cast<ExpatParser*>(parser)->allowsComments()) { | ||
| 77 | static_cast<ExpatParser*>(parser)->stopParser(); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | static void handleProcessingInstruction(void* parser, const XML_Char* /*target*/, const XML_Char* /*data*/) { | ||
| 82 | static_cast<ExpatParser*>(parser)->stopParser(); | ||
| 83 | } | ||
| 84 | |||
| 85 | static void handleDoctypeDeclaration(void* parser, const XML_Char* /*doctypeName*/, const XML_Char* /*sysid*/, const XML_Char* /*pubid*/, int /*has_internal_subset*/) { | ||
| 86 | static_cast<ExpatParser*>(parser)->stopParser(); | ||
| 87 | } | ||
| 75 | 88 | ||
| 76 | ExpatParser::ExpatParser(XMLParserClient* client) : XMLParser(client), p(new Private()) { | 89 | ExpatParser::ExpatParser(XMLParserClient* client, bool allowComments) : XMLParser(client, allowComments), p(new Private()) { |
| 77 | p->parser_ = XML_ParserCreateNS("UTF-8", NAMESPACE_SEPARATOR); | 90 | p->parser_ = XML_ParserCreateNS("UTF-8", NAMESPACE_SEPARATOR); |
| 78 | XML_SetUserData(p->parser_, this); | 91 | XML_SetUserData(p->parser_, this); |
| 79 | XML_SetElementHandler(p->parser_, handleStartElement, handleEndElement); | 92 | XML_SetElementHandler(p->parser_, handleStartElement, handleEndElement); |
| @@ -81,6 +94,9 @@ ExpatParser::ExpatParser(XMLParserClient* client) : XMLParser(client), p(new Pri | |||
| 81 | XML_SetXmlDeclHandler(p->parser_, handleXMLDeclaration); | 94 | XML_SetXmlDeclHandler(p->parser_, handleXMLDeclaration); |
| 82 | XML_SetEntityDeclHandler(p->parser_, handleEntityDeclaration); | 95 | XML_SetEntityDeclHandler(p->parser_, handleEntityDeclaration); |
| 83 | XML_SetNamespaceDeclHandler(p->parser_, handleNamespaceDeclaration, nullptr); | 96 | XML_SetNamespaceDeclHandler(p->parser_, handleNamespaceDeclaration, nullptr); |
| 97 | XML_SetCommentHandler(p->parser_, handleComment); | ||
| 98 | XML_SetProcessingInstructionHandler(p->parser_, handleProcessingInstruction); | ||
| 99 | XML_SetDoctypeDeclHandler(p->parser_, handleDoctypeDeclaration, nullptr); | ||
| 84 | } | 100 | } |
| 85 | 101 | ||
| 86 | ExpatParser::~ExpatParser() { | 102 | ExpatParser::~ExpatParser() { |
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 | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | namespace Swift { | 16 | namespace Swift { |
| 17 | class SWIFTEN_API ExpatParser : public XMLParser, public boost::noncopyable { | 17 | class SWIFTEN_API ExpatParser : public XMLParser, public boost::noncopyable { |
| 18 | public: | 18 | public: |
| 19 | ExpatParser(XMLParserClient* client); | 19 | ExpatParser(XMLParserClient* client, bool allowComments = false); |
| 20 | ~ExpatParser(); | 20 | ~ExpatParser(); |
| 21 | 21 | ||
| 22 | bool parse(const std::string& data, bool finalData = false); | 22 | bool parse(const std::string& data, bool finalData = false); |
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 | |||
| @@ -59,6 +59,24 @@ static void handleCharacterData(void* parser, const xmlChar* data, int len) { | |||
| 59 | static_cast<XMLParser*>(parser)->getClient()->handleCharacterData(std::string(reinterpret_cast<const char*>(data), static_cast<size_t>(len))); | 59 | static_cast<XMLParser*>(parser)->getClient()->handleCharacterData(std::string(reinterpret_cast<const char*>(data), static_cast<size_t>(len))); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | static void handleComment(void* parser, const xmlChar* /*data*/) { | ||
| 63 | if (!static_cast<LibXMLParser*>(parser)->allowsComments()) { | ||
| 64 | static_cast<LibXMLParser*>(parser)->stopParser(); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | static void handleEntityDeclaration(void * parser, const xmlChar* /*name*/, int /*type*/, const xmlChar* /*publicId*/, const xmlChar* /*systemId*/, xmlChar* /*content*/) { | ||
| 69 | static_cast<LibXMLParser*>(parser)->stopParser(); | ||
| 70 | } | ||
| 71 | |||
| 72 | static void handleProcessingInstruction(void* parser, const xmlChar* /*target*/, const xmlChar* /*data*/) { | ||
| 73 | static_cast<LibXMLParser*>(parser)->stopParser(); | ||
| 74 | } | ||
| 75 | |||
| 76 | static void handleExternalSubset(void* parser, const xmlChar * /*name*/, const xmlChar * /*ExternalID*/, const xmlChar * /*SystemID*/) { | ||
| 77 | static_cast<LibXMLParser*>(parser)->stopParser(); | ||
| 78 | } | ||
| 79 | |||
| 62 | static void handleError(void*, const char* /*m*/, ... ) { | 80 | static void handleError(void*, const char* /*m*/, ... ) { |
| 63 | /* | 81 | /* |
| 64 | va_list args; | 82 | va_list args; |
| @@ -73,7 +91,7 @@ static void handleWarning(void*, const char*, ... ) { | |||
| 73 | 91 | ||
| 74 | bool LibXMLParser::initialized = false; | 92 | bool LibXMLParser::initialized = false; |
| 75 | 93 | ||
| 76 | LibXMLParser::LibXMLParser(XMLParserClient* client) : XMLParser(client), p(new Private()) { | 94 | LibXMLParser::LibXMLParser(XMLParserClient* client, bool allowComments) : XMLParser(client, allowComments), p(new Private()) { |
| 77 | // Initialize libXML for multithreaded applications | 95 | // Initialize libXML for multithreaded applications |
| 78 | if (!initialized) { | 96 | if (!initialized) { |
| 79 | xmlInitParser(); | 97 | xmlInitParser(); |
| @@ -87,6 +105,10 @@ LibXMLParser::LibXMLParser(XMLParserClient* client) : XMLParser(client), p(new P | |||
| 87 | p->handler_.characters = &handleCharacterData; | 105 | p->handler_.characters = &handleCharacterData; |
| 88 | p->handler_.warning = &handleWarning; | 106 | p->handler_.warning = &handleWarning; |
| 89 | p->handler_.error = &handleError; | 107 | p->handler_.error = &handleError; |
| 108 | p->handler_.comment = &handleComment; | ||
| 109 | p->handler_.entityDecl = &handleEntityDeclaration; | ||
| 110 | p->handler_.processingInstruction = &handleProcessingInstruction; | ||
| 111 | p->handler_.externalSubset = &handleExternalSubset; | ||
| 90 | 112 | ||
| 91 | p->context_ = xmlCreatePushParserCtxt(&p->handler_, this, nullptr, 0, nullptr); | 113 | p->context_ = xmlCreatePushParserCtxt(&p->handler_, this, nullptr, 0, nullptr); |
| 92 | xmlCtxtUseOptions(p->context_, XML_PARSE_NOENT); | 114 | xmlCtxtUseOptions(p->context_, XML_PARSE_NOENT); |
| @@ -106,6 +128,7 @@ bool LibXMLParser::parse(const std::string& data, bool finalData) { | |||
| 106 | if (xmlParseChunk(p->context_, data.c_str(), static_cast<int>(data.size()), finalData) == XML_ERR_OK) { | 128 | if (xmlParseChunk(p->context_, data.c_str(), static_cast<int>(data.size()), finalData) == XML_ERR_OK) { |
| 107 | return true; | 129 | return true; |
| 108 | } | 130 | } |
| 131 | if (stopped_) return false; | ||
| 109 | xmlError* error = xmlCtxtGetLastError(p->context_); | 132 | xmlError* error = xmlCtxtGetLastError(p->context_); |
| 110 | if (error->code == XML_WAR_NS_URI || error->code == XML_WAR_NS_URI_RELATIVE) { | 133 | if (error->code == XML_WAR_NS_URI || error->code == XML_WAR_NS_URI_RELATIVE) { |
| 111 | xmlCtxtResetLastError(p->context_); | 134 | xmlCtxtResetLastError(p->context_); |
| @@ -115,4 +138,9 @@ bool LibXMLParser::parse(const std::string& data, bool finalData) { | |||
| 115 | return false; | 138 | return false; |
| 116 | } | 139 | } |
| 117 | 140 | ||
| 141 | void LibXMLParser::stopParser() { | ||
| 142 | stopped_ = true; | ||
| 143 | xmlStopParser(p->context_); | ||
| 144 | } | ||
| 145 | |||
| 118 | } | 146 | } |
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 | |||
| @@ -19,13 +19,16 @@ namespace Swift { | |||
| 19 | */ | 19 | */ |
| 20 | class LibXMLParser : public XMLParser, public boost::noncopyable { | 20 | class LibXMLParser : public XMLParser, public boost::noncopyable { |
| 21 | public: | 21 | public: |
| 22 | LibXMLParser(XMLParserClient* client); | 22 | LibXMLParser(XMLParserClient* client, bool allowComments = false); |
| 23 | virtual ~LibXMLParser(); | 23 | virtual ~LibXMLParser(); |
| 24 | 24 | ||
| 25 | bool parse(const std::string& data, bool finalData = false); | 25 | bool parse(const std::string& data, bool finalData = false); |
| 26 | 26 | ||
| 27 | void stopParser(); | ||
| 28 | |||
| 27 | private: | 29 | private: |
| 28 | static bool initialized; | 30 | static bool initialized; |
| 31 | bool stopped_ = false; | ||
| 29 | 32 | ||
| 30 | struct Private; | 33 | struct Private; |
| 31 | const std::unique_ptr<Private> p; | 34 | const std::unique_ptr<Private> p; |
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 | |||
| @@ -19,7 +19,7 @@ namespace Swift { | |||
| 19 | class PayloadsParserTester : public XMLParserClient { | 19 | class PayloadsParserTester : public XMLParserClient { |
| 20 | public: | 20 | public: |
| 21 | PayloadsParserTester() : level(0) { | 21 | PayloadsParserTester() : level(0) { |
| 22 | xmlParser = PlatformXMLParserFactory().createXMLParser(this); | 22 | xmlParser = PlatformXMLParserFactory().createXMLParser(this, false); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | bool parse(const std::string& data) { | 25 | bool parse(const std::string& data) { |
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 | |||
| @@ -20,11 +20,11 @@ namespace Swift { | |||
| 20 | PlatformXMLParserFactory::PlatformXMLParserFactory() { | 20 | PlatformXMLParserFactory::PlatformXMLParserFactory() { |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | std::unique_ptr<XMLParser> PlatformXMLParserFactory::createXMLParser(XMLParserClient* client) { | 23 | std::unique_ptr<XMLParser> PlatformXMLParserFactory::createXMLParser(XMLParserClient* client, bool allowComments) { |
| 24 | #ifdef HAVE_LIBXML | 24 | #ifdef HAVE_LIBXML |
| 25 | return std::make_unique<LibXMLParser>(client); | 25 | return std::make_unique<LibXMLParser>(client, allowComments); |
| 26 | #else | 26 | #else |
| 27 | return std::make_unique<ExpatParser>(client); | 27 | return std::make_unique<ExpatParser>(client, allowComments); |
| 28 | #endif | 28 | #endif |
| 29 | } | 29 | } |
| 30 | 30 | ||
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 | |||
| @@ -14,6 +14,6 @@ namespace Swift { | |||
| 14 | public: | 14 | public: |
| 15 | PlatformXMLParserFactory(); | 15 | PlatformXMLParserFactory(); |
| 16 | 16 | ||
| 17 | virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*); | 17 | virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*, bool allowComments = false); |
| 18 | }; | 18 | }; |
| 19 | } | 19 | } |
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 | |||
| @@ -39,6 +39,10 @@ class XMLParserTest : public CppUnit::TestFixture { | |||
| 39 | CPPUNIT_TEST(testParse_InternalEntity); | 39 | CPPUNIT_TEST(testParse_InternalEntity); |
| 40 | //CPPUNIT_TEST(testParse_UndefinedPrefix); | 40 | //CPPUNIT_TEST(testParse_UndefinedPrefix); |
| 41 | //CPPUNIT_TEST(testParse_UndefinedAttributePrefix); | 41 | //CPPUNIT_TEST(testParse_UndefinedAttributePrefix); |
| 42 | CPPUNIT_TEST(testParse_AllowCommentsInXML); | ||
| 43 | CPPUNIT_TEST(testParse_DisallowCommentsInXML); | ||
| 44 | CPPUNIT_TEST(testParse_Doctype); | ||
| 45 | CPPUNIT_TEST(testParse_ProcessingInstructions); | ||
| 42 | CPPUNIT_TEST_SUITE_END(); | 46 | CPPUNIT_TEST_SUITE_END(); |
| 43 | 47 | ||
| 44 | public: | 48 | public: |
| @@ -185,7 +189,7 @@ class XMLParserTest : public CppUnit::TestFixture { | |||
| 185 | } | 189 | } |
| 186 | 190 | ||
| 187 | void testParse_UnhandledXML() { | 191 | void testParse_UnhandledXML() { |
| 188 | ParserType testling(&client_); | 192 | ParserType testling(&client_, true); |
| 189 | 193 | ||
| 190 | CPPUNIT_ASSERT(testling.parse("<iq><!-- Testing --></iq>")); | 194 | CPPUNIT_ASSERT(testling.parse("<iq><!-- Testing --></iq>")); |
| 191 | 195 | ||
| @@ -331,13 +335,44 @@ class XMLParserTest : public CppUnit::TestFixture { | |||
| 331 | void testParse_UndefinedAttributePrefix() { | 335 | void testParse_UndefinedAttributePrefix() { |
| 332 | ParserType testling(&client_); | 336 | ParserType testling(&client_); |
| 333 | 337 | ||
| 334 | CPPUNIT_ASSERT(testling.parse( | 338 | CPPUNIT_ASSERT(testling.parse("<foo bar:baz='bla'/>")); |
| 335 | "<foo bar:baz='bla'/>")); | ||
| 336 | 339 | ||
| 337 | CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.getEntries().size()); | 340 | CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.getEntries().size()); |
| 338 | CPPUNIT_ASSERT_EQUAL(std::string("bar:baz"), client_.events[0].attributes.getEntries()[0].getAttribute().getName()); | 341 | CPPUNIT_ASSERT_EQUAL(std::string("bar:baz"), client_.events[0].attributes.getEntries()[0].getAttribute().getName()); |
| 339 | } | 342 | } |
| 340 | 343 | ||
| 344 | void testParse_AllowCommentsInXML() { | ||
| 345 | ParserType testling(&client_, true); | ||
| 346 | |||
| 347 | CPPUNIT_ASSERT(testling.parse("<message><!-- Some More Comments Testing --></message>")); | ||
| 348 | |||
| 349 | CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), client_.events.size()); | ||
| 350 | |||
| 351 | CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); | ||
| 352 | CPPUNIT_ASSERT_EQUAL(std::string("message"), client_.events[0].data); | ||
| 353 | |||
| 354 | CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[1].type); | ||
| 355 | CPPUNIT_ASSERT_EQUAL(std::string("message"), client_.events[1].data); | ||
| 356 | } | ||
| 357 | |||
| 358 | void testParse_DisallowCommentsInXML() { | ||
| 359 | ParserType testling(&client_); | ||
| 360 | |||
| 361 | CPPUNIT_ASSERT(!testling.parse("<message><!-- Some More Comments Testing --></message>")); | ||
| 362 | } | ||
| 363 | |||
| 364 | void testParse_Doctype() { | ||
| 365 | ParserType testling(&client_); | ||
| 366 | |||
| 367 | CPPUNIT_ASSERT(!testling.parse("<!DOCTYPE greeting SYSTEM \"hello.dtd\">")); | ||
| 368 | } | ||
| 369 | |||
| 370 | void testParse_ProcessingInstructions() { | ||
| 371 | ParserType testling(&client_); | ||
| 372 | |||
| 373 | CPPUNIT_ASSERT(!testling.parse("<?xml-stylesheet type=\"text/xsl\" href=\"Sample.xsl\"?>")); | ||
| 374 | } | ||
| 375 | |||
| 341 | private: | 376 | private: |
| 342 | class Client : public XMLParserClient { | 377 | class Client : public XMLParserClient { |
| 343 | public: | 378 | public: |
| @@ -378,6 +413,7 @@ class XMLParserTest : public CppUnit::TestFixture { | |||
| 378 | void handleNamespaceDeclaration(const std::string& prefix, const std::string& uri) override { | 413 | void handleNamespaceDeclaration(const std::string& prefix, const std::string& uri) override { |
| 379 | namespaces_[prefix] = uri; | 414 | namespaces_[prefix] = uri; |
| 380 | } | 415 | } |
| 416 | |||
| 381 | std::vector<Event> events; | 417 | std::vector<Event> events; |
| 382 | private: | 418 | private: |
| 383 | NamespaceMap namespaces_; | 419 | NamespaceMap namespaces_; |
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 | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | namespace Swift { | 9 | namespace Swift { |
| 10 | 10 | ||
| 11 | XMLParser::XMLParser(XMLParserClient* client) : client_(client) { | 11 | XMLParser::XMLParser(XMLParserClient* client, bool allowComments) : client_(client), allowComments_(allowComments){ |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | XMLParser::~XMLParser() { | 14 | XMLParser::~XMLParser() { |
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 | |||
| @@ -15,7 +15,7 @@ namespace Swift { | |||
| 15 | 15 | ||
| 16 | class SWIFTEN_API XMLParser { | 16 | class SWIFTEN_API XMLParser { |
| 17 | public: | 17 | public: |
| 18 | XMLParser(XMLParserClient* client); | 18 | XMLParser(XMLParserClient* client, bool allowComments = false); |
| 19 | virtual ~XMLParser(); | 19 | virtual ~XMLParser(); |
| 20 | 20 | ||
| 21 | virtual bool parse(const std::string& data, bool finalData = false) = 0; | 21 | virtual bool parse(const std::string& data, bool finalData = false) = 0; |
| @@ -24,7 +24,12 @@ namespace Swift { | |||
| 24 | return client_; | 24 | return client_; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | bool allowsComments() const { | ||
| 28 | return allowComments_; | ||
| 29 | } | ||
| 30 | |||
| 27 | private: | 31 | private: |
| 28 | XMLParserClient* client_; | 32 | XMLParserClient* client_; |
| 33 | const bool allowComments_ = false; | ||
| 29 | }; | 34 | }; |
| 30 | } | 35 | } |
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 | |||
| @@ -18,6 +18,6 @@ namespace Swift { | |||
| 18 | public: | 18 | public: |
| 19 | virtual ~XMLParserFactory(); | 19 | virtual ~XMLParserFactory(); |
| 20 | 20 | ||
| 21 | virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*) = 0; | 21 | virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*, bool allowComments = false) = 0; |
| 22 | }; | 22 | }; |
| 23 | } | 23 | } |
Swift