#5300 - Invalid encoding in XML output (use escape sequence string for non-printable characters)

This commit is contained in:
Alexander Mai 2014-04-13 09:50:57 +02:00
parent 71b306ff64
commit 73fc3d6a13
2 changed files with 31 additions and 1 deletions

View File

@ -25,6 +25,7 @@
#include <tinyxml2.h>
#include <cassert>
#include <iomanip>
#include <sstream>
#include <vector>
@ -211,6 +212,27 @@ std::string ErrorLogger::ErrorMessage::getXMLFooter(int xml_version)
return (xml_version<=1) ? "</results>" : " </errors>\n</results>";
}
// There is no utf-8 support around but the strings should at least be safe for to tinyxml2.
// See #5300 "Invalid encoding in XML output"
static std::string fixInvalidChars(const std::string& raw)
{
std::string result;
result.reserve(raw.length());
std::string::const_iterator from=raw.begin();
while (from!=raw.end()) {
if (std::isprint(*from)) {
result.push_back(*from);
} else {
std::ostringstream es;
// straight cast to (unsigned) doesn't work out.
es << '\\' << std::setbase(8) << std::setw(3) << std::setfill('0') << (unsigned)(unsigned char)*from;
result += es.str();
}
++from;
}
return result;
}
std::string ErrorLogger::ErrorMessage::toXML(bool verbose, int version) const
{
// The default xml format
@ -239,7 +261,7 @@ std::string ErrorLogger::ErrorMessage::toXML(bool verbose, int version) const
printer.PushAttribute("id", _id.c_str());
printer.PushAttribute("severity", Severity::toString(_severity).c_str());
printer.PushAttribute("msg", _shortMessage.c_str());
printer.PushAttribute("verbose", _verboseMessage.c_str());
printer.PushAttribute("verbose", fixInvalidChars(_verboseMessage).c_str());
if (_inconclusive)
printer.PushAttribute("inconclusive", "true");

View File

@ -46,6 +46,7 @@ private:
TEST_CASE(ToVerboseXmlLocations);
TEST_CASE(ToXmlV2);
TEST_CASE(ToXmlV2Locations);
TEST_CASE(ToXmlV2Encoding);
// Inconclusive results in xml reports..
TEST_CASE(InconclusiveXml);
@ -215,6 +216,13 @@ private:
ASSERT_EQUALS(message, msg.toXML(false, 2));
}
void ToXmlV2Encoding() const {
std::list<ErrorLogger::ErrorMessage::FileLocation> locs;
ErrorMessage msg(locs, Severity::error, "Programming error.\nComparing \"\203\" with \"\003\"", "errorId", false);
const std::string message(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error.\" verbose=\"Comparing &quot;\\203&quot; with &quot;\\003&quot;\"/>");
ASSERT_EQUALS(message, msg.toXML(false, 2));
}
void InconclusiveXml() const {
// Location
std::list<ErrorLogger::ErrorMessage::FileLocation> locs(1, fooCpp5);