diff --git a/src/XMLDocument.h b/src/XMLDocument.h index 71e6136d7..9d706b831 100644 --- a/src/XMLDocument.h +++ b/src/XMLDocument.h @@ -38,7 +38,7 @@ #include #include -#include +#include namespace digidoc { @@ -364,9 +364,13 @@ struct XMLDocument: public unique_free_d, public XMLNode d = {}; } - XMLDocument(const std::string &path, const XMLName &n = {}) noexcept - : XMLDocument(path.empty() ? nullptr : xmlParseFile(path.c_str()), n) - {} + XMLDocument(const std::string &path, const XMLName &n = {}) + { + if(path.empty()) + return; + if(std::ifstream f{path}) + *this = openStream(f, n); + } template static XMLDocument open(F &&f, const XMLName &name = {}, bool hugeFile = false) diff --git a/src/XmlConf.cpp b/src/XmlConf.cpp index c3c31fcff..ec27e4e90 100644 --- a/src/XmlConf.cpp +++ b/src/XmlConf.cpp @@ -124,7 +124,9 @@ XmlConf::Private::Private(Conf *self, const string &path, string schema) auto XmlConf::Private::loadDoc(const string &path) const { LIBXML_TEST_VERSION - auto doc = XMLDocument(path, {"configuration"}); + XMLDocument doc; + try { doc = XMLDocument(path, {"configuration"}); } + catch(const Exception &) {} if(!doc) { WARN("Failed to parse configuration: %s", path.c_str()); diff --git a/src/crypto/X509Crypto.cpp b/src/crypto/X509Crypto.cpp index 32f2a83ea..7ee9937e1 100644 --- a/src/crypto/X509Crypto.cpp +++ b/src/crypto/X509Crypto.cpp @@ -126,7 +126,7 @@ int X509Crypto::compareIssuerToString(string_view name) const } } - X509_NAME *issuer = X509_get_issuer_name(cert.handle()); + const X509_NAME *issuer = X509_get_issuer_name(cert.handle()); for(const auto &[key, val]: data) { auto obj = find(list.cbegin(), list.cend(), key); diff --git a/test/libdigidocpp_boost.cpp b/test/libdigidocpp_boost.cpp index 111bcc919..4335aed77 100644 --- a/test/libdigidocpp_boost.cpp +++ b/test/libdigidocpp_boost.cpp @@ -686,8 +686,8 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(XMLTestSuite) BOOST_AUTO_TEST_CASE(XMLBomb) { - BOOST_CHECK_EQUAL(XMLDocument("xml-bomb-attr.xml"), false); - BOOST_CHECK_EQUAL(XMLDocument("xml-bomb-cont.xml"), false); + BOOST_CHECK_THROW(XMLDocument("xml-bomb-attr.xml"), Exception); + BOOST_CHECK_THROW(XMLDocument("xml-bomb-cont.xml"), Exception); if(std::fstream f{"xml-bomb-attr.xml"}) BOOST_CHECK_THROW(XMLDocument::openStream(f), Exception); if(std::fstream f{"xml-bomb-cont.xml"}) @@ -736,6 +736,7 @@ BOOST_AUTO_TEST_CASE(XMLXXE) "]>&sentinel;", }; + size_t payloadIndex = 0; for(const auto &payload : payloads) { for(bool huge : {false, true}) { std::istringstream is{std::string(payload)}; @@ -745,6 +746,21 @@ BOOST_AUTO_TEST_CASE(XMLXXE) BOOST_CHECK(!text.contains("XXESENTINEL")); xmlFree(raw); } + + const auto path = (fs::temp_directory_path() / + ("libdigidocpp-xxe-payload-" + std::to_string(payloadIndex++) + ".xml")).string(); + std::ofstream out{path, std::ofstream::binary}; + BOOST_REQUIRE(out.is_open()); + out << payload; + out.close(); + BOOST_REQUIRE(out.good()); + + auto doc = XMLDocument(path); + xmlChar *raw = xmlNodeGetContent(doc.d); + std::string_view text = raw ? (const char*)raw : ""; + BOOST_CHECK(!text.contains("XXESENTINEL")); + xmlFree(raw); + fs::remove(path); } } BOOST_AUTO_TEST_SUITE_END()