diff options
| author | Edwin Mons <edwin.mons@isode.com> | 2018-11-09 09:15:38 (GMT) |
|---|---|---|
| committer | Edwin Mons <edwin.mons@isode.com> | 2018-11-09 13:43:02 (GMT) |
| commit | 56384396e5501ebcf7276caa2cb561023d3c3d12 (patch) | |
| tree | a9365158591c420fe4fe16e661264b9d56f54bce | |
| parent | a45eed2d826f60a20dfd1f4f06df37d1f83263f8 (diff) | |
| download | swift-56384396e5501ebcf7276caa2cb561023d3c3d12.zip swift-56384396e5501ebcf7276caa2cb561023d3c3d12.tar.bz2 | |
Remove numeric_casts from XML parsers
The code has been updated to use asserts where a sensible recovery path
was deemed impossible, and a conditional return for parse. In general,
our XML parsing will fail for any single parse of a document over
roughly 2 2GiB, which is probably not going to be a practical issue soon.
Test-Information:
Unit tests pass on macOS 10.13 using Expat and Debian 9 using LibXML
Change-Id: I3a8da802860028ea278b322af081c2b22b55a442
| -rw-r--r-- | Swiften/Parser/ExpatParser.cpp | 8 | ||||
| -rw-r--r-- | Swiften/Parser/LibXMLParser.cpp | 16 |
2 files changed, 15 insertions, 9 deletions
diff --git a/Swiften/Parser/ExpatParser.cpp b/Swiften/Parser/ExpatParser.cpp index 77d959c..8415c42 100644 --- a/Swiften/Parser/ExpatParser.cpp +++ b/Swiften/Parser/ExpatParser.cpp | |||
| @@ -7,13 +7,12 @@ | |||
| 7 | #include <Swiften/Parser/ExpatParser.h> | 7 | #include <Swiften/Parser/ExpatParser.h> |
| 8 | 8 | ||
| 9 | #include <cassert> | 9 | #include <cassert> |
| 10 | #include <limits> | ||
| 10 | #include <memory> | 11 | #include <memory> |
| 11 | #include <string> | 12 | #include <string> |
| 12 | 13 | ||
| 13 | #include <expat.h> | 14 | #include <expat.h> |
| 14 | 15 | ||
| 15 | #include <boost/numeric/conversion/cast.hpp> | ||
| 16 | |||
| 17 | #include <Swiften/Base/String.h> | 16 | #include <Swiften/Base/String.h> |
| 18 | #include <Swiften/Parser/XMLParserClient.h> | 17 | #include <Swiften/Parser/XMLParserClient.h> |
| 19 | 18 | ||
| @@ -84,7 +83,10 @@ ExpatParser::~ExpatParser() { | |||
| 84 | } | 83 | } |
| 85 | 84 | ||
| 86 | bool ExpatParser::parse(const std::string& data) { | 85 | bool ExpatParser::parse(const std::string& data) { |
| 87 | bool success = XML_Parse(p->parser_, data.c_str(), boost::numeric_cast<int>(data.size()), false) == XML_STATUS_OK; | 86 | if (data.size() > std::numeric_limits<int>::max()) { |
| 87 | return false; | ||
| 88 | } | ||
| 89 | bool success = XML_Parse(p->parser_, data.c_str(), static_cast<int>(data.size()), false) == XML_STATUS_OK; | ||
| 88 | /*if (!success) { | 90 | /*if (!success) { |
| 89 | std::cout << "ERROR: " << XML_ErrorString(XML_GetErrorCode(p->parser_)) << " while parsing " << data << std::endl; | 91 | std::cout << "ERROR: " << XML_ErrorString(XML_GetErrorCode(p->parser_)) << " while parsing " << data << std::endl; |
| 90 | }*/ | 92 | }*/ |
diff --git a/Swiften/Parser/LibXMLParser.cpp b/Swiften/Parser/LibXMLParser.cpp index be0a92d..5bd3737 100644 --- a/Swiften/Parser/LibXMLParser.cpp +++ b/Swiften/Parser/LibXMLParser.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2016 Isode Limited. | 2 | * Copyright (c) 2010-2018 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -8,11 +8,10 @@ | |||
| 8 | 8 | ||
| 9 | #include <cassert> | 9 | #include <cassert> |
| 10 | #include <cstring> | 10 | #include <cstring> |
| 11 | #include <limits> | ||
| 11 | #include <memory> | 12 | #include <memory> |
| 12 | #include <string> | 13 | #include <string> |
| 13 | 14 | ||
| 14 | #include <boost/numeric/conversion/cast.hpp> | ||
| 15 | |||
| 16 | #include <libxml/parser.h> | 15 | #include <libxml/parser.h> |
| 17 | 16 | ||
| 18 | #include <Swiften/Base/Log.h> | 17 | #include <Swiften/Base/Log.h> |
| @@ -36,11 +35,12 @@ static void handleStartElement(void* parser, const xmlChar* name, const xmlChar* | |||
| 36 | if (attributes[i+2]) { | 35 | if (attributes[i+2]) { |
| 37 | attributeNS = std::string(reinterpret_cast<const char*>(attributes[i+2])); | 36 | attributeNS = std::string(reinterpret_cast<const char*>(attributes[i+2])); |
| 38 | } | 37 | } |
| 38 | assert(attributes[i+4] >= attributes[i+3]); | ||
| 39 | attributeValues.addAttribute( | 39 | attributeValues.addAttribute( |
| 40 | std::string(reinterpret_cast<const char*>(attributes[i])), | 40 | std::string(reinterpret_cast<const char*>(attributes[i])), |
| 41 | attributeNS, | 41 | attributeNS, |
| 42 | std::string(reinterpret_cast<const char*>(attributes[i+3]), | 42 | std::string(reinterpret_cast<const char*>(attributes[i+3]), |
| 43 | boost::numeric_cast<size_t>(attributes[i+4]-attributes[i+3]))); | 43 | static_cast<size_t>(attributes[i+4]-attributes[i+3]))); |
| 44 | } | 44 | } |
| 45 | static_cast<XMLParser*>(parser)->getClient()->handleStartElement(reinterpret_cast<const char*>(name), (xmlns ? reinterpret_cast<const char*>(xmlns) : std::string()), attributeValues); | 45 | static_cast<XMLParser*>(parser)->getClient()->handleStartElement(reinterpret_cast<const char*>(name), (xmlns ? reinterpret_cast<const char*>(xmlns) : std::string()), attributeValues); |
| 46 | } | 46 | } |
| @@ -50,7 +50,8 @@ static void handleEndElement(void *parser, const xmlChar* name, const xmlChar*, | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | static void handleCharacterData(void* parser, const xmlChar* data, int len) { | 52 | static void handleCharacterData(void* parser, const xmlChar* data, int len) { |
| 53 | static_cast<XMLParser*>(parser)->getClient()->handleCharacterData(std::string(reinterpret_cast<const char*>(data), boost::numeric_cast<size_t>(len))); | 53 | assert(len >= 0); |
| 54 | static_cast<XMLParser*>(parser)->getClient()->handleCharacterData(std::string(reinterpret_cast<const char*>(data), static_cast<size_t>(len))); | ||
| 54 | } | 55 | } |
| 55 | 56 | ||
| 56 | static void handleError(void*, const char* /*m*/, ... ) { | 57 | static void handleError(void*, const char* /*m*/, ... ) { |
| @@ -94,7 +95,10 @@ LibXMLParser::~LibXMLParser() { | |||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | bool LibXMLParser::parse(const std::string& data) { | 97 | bool LibXMLParser::parse(const std::string& data) { |
| 97 | if (xmlParseChunk(p->context_, data.c_str(), boost::numeric_cast<int>(data.size()), false) == XML_ERR_OK) { | 98 | if (data.size() > std::numeric_limits<int>::max()) { |
| 99 | return false; | ||
| 100 | } | ||
| 101 | if (xmlParseChunk(p->context_, data.c_str(), static_cast<int>(data.size()), false) == XML_ERR_OK) { | ||
| 98 | return true; | 102 | return true; |
| 99 | } | 103 | } |
| 100 | xmlError* error = xmlCtxtGetLastError(p->context_); | 104 | xmlError* error = xmlCtxtGetLastError(p->context_); |
Swift