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 /Swiften/Parser/LibXMLParser.cpp | |
| 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
Diffstat (limited to 'Swiften/Parser/LibXMLParser.cpp')
| -rw-r--r-- | Swiften/Parser/LibXMLParser.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
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 | } |
Swift