diff --git a/src/SignatureXAdES_B.cpp b/src/SignatureXAdES_B.cpp index 4fcdb9694..47208720d 100644 --- a/src/SignatureXAdES_B.cpp +++ b/src/SignatureXAdES_B.cpp @@ -742,7 +742,7 @@ void SignatureXAdES_B::setSignatureProductionPlace(string_view name, * * @param roles signer roles. */ -void SignatureXAdES_B::setSignerRoles(string_view name, const vector &roles) noexcept +void SignatureXAdES_B::setSignerRoles(string_view name, const vector &roles) { if(roles.empty()) return; diff --git a/src/SignatureXAdES_B.h b/src/SignatureXAdES_B.h index 56f12e485..aa212fdf7 100644 --- a/src/SignatureXAdES_B.h +++ b/src/SignatureXAdES_B.h @@ -112,7 +112,7 @@ namespace digidoc void setSignatureProductionPlace(std::string_view name, const std::string &city, const std::string &streetAddress, const std::string &stateOrProvince, const std::string &postalCode, const std::string &countryName) noexcept; - void setSignerRoles(std::string_view name, const std::vector &signerRoles) noexcept; + void setSignerRoles(std::string_view name, const std::vector &signerRoles); constexpr XMLNode V1orV2(std::string_view v1, std::string_view v2) const noexcept; // offline checks diff --git a/src/XMLDocument.h b/src/XMLDocument.h index f9e7b94f9..d97d3ca6c 100644 --- a/src/XMLDocument.h +++ b/src/XMLDocument.h @@ -229,10 +229,21 @@ struct XMLNode: public XMLElem return from_base64(operator sv()); } - XMLNode& operator=(sv text) noexcept + XMLNode& operator=(sv text) { if(!d) return *this; + const char *utf = text.cbegin(); + int len = int(text.size()); + while (utf < text.cend()) { + int uc = xmlGetUTF8Char((const unsigned char *) utf, &len); + if (len < 1) { + THROW("Invalid utf8 string in XML content"); + } else if (((uc < 0x20) && (uc != 0x9) && (uc != 0xa) && (uc != 0xd)) || (uc == 0xfffe) || (uc == 0xffff)) { + THROW("Invalid character '0x%2x' in XML content", uc); + } + utf += len; + } xmlNodeSetContentLen(d, nullptr, 0); if(!text.empty()) xmlNodeAddContentLen(d, pcxmlChar(text.data()), int(text.length())); diff --git a/src/crypto/Signer.cpp b/src/crypto/Signer.cpp index b36a0e4c5..0381e6bba 100644 --- a/src/crypto/Signer.cpp +++ b/src/crypto/Signer.cpp @@ -73,6 +73,7 @@ Signer::~Signer() = default; * @param stateOrProvince * @param postalCode * @param countryName + * The strings have to be utf8 encoded and not contain any control values (any char < 0x20 except 0x9, 0xa and 0xd) */ void Signer::setSignatureProductionPlace(const string &city, const string &stateOrProvince, const string &postalCode, const string &countryName) @@ -90,6 +91,7 @@ void Signer::setSignatureProductionPlace(const string &city, * @param stateOrProvince * @param postalCode * @param countryName + * The strings have to be utf8 encoded and not contain any control values (any char < 0x20 except 0x9, 0xa and 0xd) */ void Signer::setSignatureProductionPlaceV2(const string &city, const string &streetAddress, const string &stateOrProvince, const string &postalCode, const string &countryName) @@ -194,6 +196,7 @@ void Signer::setProfile(const string &profile) /** * Sets signature roles according XAdES standard. The parameter may contain the signer’s role and optionally the signer’s resolution. Note that only one signer role value (i.e. one <ClaimedRole> XML element) should be used. * If the signer role contains both role and resolution then they must be separated with a slash mark, e.g. “role / resolution”. + * The strings have to be utf8 encoded and not contain any control values (any char < 0x20 except 0x9, 0xa and 0xd) */ void Signer::setSignerRoles(const vector &signerRoles) {