summaryrefslogtreecommitdiffstats
path: root/src/testlib/qxmltestlogger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/testlib/qxmltestlogger.cpp')
-rw-r--r--src/testlib/qxmltestlogger.cpp205
1 files changed, 168 insertions, 37 deletions
diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp
index bba98da..0606ced 100644
--- a/src/testlib/qxmltestlogger.cpp
+++ b/src/testlib/qxmltestlogger.cpp
@@ -46,6 +46,7 @@
#include "QtTest/private/qxmltestlogger_p.h"
#include "QtTest/private/qtestresult_p.h"
#include "QtTest/private/qbenchmark_p.h"
+#include "QtTest/qtestcase.h"
QT_BEGIN_NAMESPACE
@@ -90,27 +91,27 @@ namespace QTest {
}
-QXmlTestLogger::QXmlTestLogger(XmlMode mode ):
- xmlmode(mode)
+QXmlTestLogger::QXmlTestLogger(XmlMode mode )
+ :xmlmode(mode)
{
}
QXmlTestLogger::~QXmlTestLogger()
{
-
}
-
void QXmlTestLogger::startLogging()
{
QAbstractTestLogger::startLogging();
char buf[1024];
if (xmlmode == QXmlTestLogger::Complete) {
+ char quotedTc[900];
+ xmlQuote(quotedTc, QTestResult::currentTestObjectName(), sizeof(quotedTc));
QTest::qt_snprintf(buf, sizeof(buf),
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
- "<TestCase name=\"%s\">\n", QTestResult::currentTestObjectName());
+ "<TestCase name=\"%s\">\n", quotedTc);
outputString(buf);
}
@@ -134,7 +135,9 @@ void QXmlTestLogger::stopLogging()
void QXmlTestLogger::enterTestFunction(const char *function)
{
char buf[1024];
- QTest::qt_snprintf(buf, sizeof(buf), "<TestFunction name=\"%s\">\n", function);
+ char quotedFunction[950];
+ xmlQuote(quotedFunction, function, sizeof(quotedFunction));
+ QTest::qt_snprintf(buf, sizeof(buf), "<TestFunction name=\"%s\">\n", quotedFunction);
outputString(buf);
}
@@ -158,18 +161,18 @@ static const char *incidentFormatString(bool noDescription, bool noTag)
return "<Incident type=\"%s\" file=\"%s\" line=\"%d\" />\n";
else
return "<Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
- "</Incident>\n";
+ " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
+ "</Incident>\n";
} else {
if (noTag)
return "<Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <Description><![CDATA[%s%s%s%s]]></Description>\n"
- "</Incident>\n";
+ " <Description><![CDATA[%s%s%s%s]]></Description>\n"
+ "</Incident>\n";
else
return "<Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
- " <Description><![CDATA[%s]]></Description>\n"
- "</Incident>\n";
+ " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
+ " <Description><![CDATA[%s]]></Description>\n"
+ "</Incident>\n";
}
}
@@ -185,40 +188,51 @@ static const char *messageFormatString(bool noDescription, bool noTag)
return "<Message type=\"%s\" file=\"%s\" line=\"%d\" />\n";
else
return "<Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
- "</Message>\n";
+ " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
+ "</Message>\n";
} else {
if (noTag)
return "<Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <Description><![CDATA[%s%s%s%s]]></Description>\n"
- "</Message>\n";
+ " <Description><![CDATA[%s%s%s%s]]></Description>\n"
+ "</Message>\n";
else
return "<Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
- " <Description><![CDATA[%s]]></Description>\n"
- "</Message>\n";
+ " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
+ " <Description><![CDATA[%s]]></Description>\n"
+ "</Message>\n";
}
}
} // namespace
void QXmlTestLogger::addIncident(IncidentTypes type, const char *description,
- const char *file, int line)
+ const char *file, int line)
{
- char buf[1536];
+ // buffer must be large enough to hold all quoted/cdata buffers plus the format string itself
+ char buf[5000];
const char *tag = QTestResult::currentDataTag();
const char *gtag = QTestResult::currentGlobalDataTag();
const char *filler = (tag && gtag) ? ":" : "";
const bool notag = QTest::isEmpty(tag) && QTest::isEmpty(gtag);
+ char quotedFile[1024];
+ char cdataGtag[1024];
+ char cdataTag[1024];
+ char cdataDescription[1024];
+
+ xmlQuote(quotedFile, file, sizeof(quotedFile));
+ xmlCdata(cdataGtag, gtag, sizeof(cdataGtag));
+ xmlCdata(cdataTag, tag, sizeof(cdataTag));
+ xmlCdata(cdataDescription, description, sizeof(cdataDescription));
+
QTest::qt_snprintf(buf, sizeof(buf),
QTest::incidentFormatString(QTest::isEmpty(description), notag),
QTest::xmlIncidentType2String(type),
- file ? file : "", line,
- gtag ? gtag : "",
+ quotedFile, line,
+ cdataGtag,
filler,
- tag ? tag : "",
- description ? description : "");
+ cdataTag,
+ cdataDescription);
outputString(buf);
}
@@ -226,39 +240,156 @@ void QXmlTestLogger::addIncident(IncidentTypes type, const char *description,
void QXmlTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
{
char buf[1536];
+ char quotedMetric[64];
+ char quotedTag[1024];
+
+ xmlQuote(quotedMetric,
+ QBenchmarkGlobalData::current->measurer->metricText().toAscii().constData(),
+ sizeof(quotedMetric));
+ xmlQuote(quotedTag, result.context.tag.toAscii().constData(), sizeof(quotedTag));
+
QTest::qt_snprintf(
buf, sizeof(buf),
QTest::benchmarkResultFormatString(),
- QBenchmarkGlobalData::current->measurer->metricText().toAscii().data(),
- result.context.tag.toAscii().data(),
+ quotedMetric,
+ quotedTag,
QByteArray::number(result.value).constData(), //no 64-bit qt_snprintf support
- result.iterations);
+ result.iterations);
outputString(buf);
}
void QXmlTestLogger::addMessage(MessageTypes type, const char *message,
const char *file, int line)
{
- char buf[1536];
- char msgbuf[1024];
+ char buf[5000];
const char *tag = QTestResult::currentDataTag();
const char *gtag = QTestResult::currentGlobalDataTag();
const char *filler = (tag && gtag) ? ":" : "";
const bool notag = QTest::isEmpty(tag) && QTest::isEmpty(gtag);
- QTest::qt_snprintf(msgbuf, sizeof(msgbuf), "%s",
- message ? message : "");
+ char quotedFile[1024];
+ char cdataGtag[1024];
+ char cdataTag[1024];
+ char cdataDescription[1024];
+
+ xmlQuote(quotedFile, file, sizeof(quotedFile));
+ xmlCdata(cdataGtag, gtag, sizeof(cdataGtag));
+ xmlCdata(cdataTag, tag, sizeof(cdataTag));
+ xmlCdata(cdataDescription, message, sizeof(cdataDescription));
QTest::qt_snprintf(buf, sizeof(buf),
QTest::messageFormatString(QTest::isEmpty(message), notag),
QTest::xmlMessageType2String(type),
- file ? file : "", line,
- gtag ? gtag : "",
+ quotedFile, line,
+ cdataGtag,
filler,
- tag ? tag : "",
- msgbuf);
+ cdataTag,
+ cdataDescription);
outputString(buf);
}
+/*
+ Copy up to n characters from the src string into dest, escaping any special
+ XML characters as necessary so that dest is suitable for use in an XML
+ quoted attribute string.
+*/
+void QXmlTestLogger::xmlQuote(char* dest, char const* src, size_t n)
+{
+ if (n == 0) return;
+
+ *dest = 0;
+ if (!src) return;
+
+ char* end = dest + n;
+
+ while (dest < end) {
+ switch (*src) {
+
+#define MAP_ENTITY(chr, ent) \
+ case chr: \
+ if (dest + sizeof(ent) < end) { \
+ strcpy(dest, ent); \
+ dest += sizeof(ent) - 1; \
+ } \
+ else { \
+ *dest = 0; \
+ return; \
+ } \
+ ++src; \
+ break;
+
+ MAP_ENTITY('>', "&gt;");
+ MAP_ENTITY('<', "&lt;");
+ MAP_ENTITY('\'', "&apos;");
+ MAP_ENTITY('"', "&quot;");
+ MAP_ENTITY('&', "&amp;");
+
+ // not strictly necessary, but allows handling of comments without
+ // having to explicitly look for `--'
+ MAP_ENTITY('-', "&#x002D;");
+
+#undef MAP_ENTITY
+
+ case 0:
+ *dest = 0;
+ return;
+
+ default:
+ *dest = *src;
+ ++dest;
+ ++src;
+ break;
+ }
+ }
+
+ // If we get here, dest was completely filled (dest == end)
+ *(dest-1) = 0;
+}
+
+/*
+ Copy up to n characters from the src string into dest, escaping any
+ special strings such that dest is suitable for use in an XML CDATA section.
+*/
+void QXmlTestLogger::xmlCdata(char* dest, char const* src, size_t n)
+{
+ if (!n) return;
+
+ if (!src || n == 1) {
+ *dest = 0;
+ return;
+ }
+
+ char const CDATA_END[] = "]]>";
+ char const CDATA_END_ESCAPED[] = "]]]><![CDATA[]>";
+
+ char* end = dest + n;
+ while (dest < end) {
+ if (!*src) {
+ *dest = 0;
+ return;
+ }
+
+ if (!strncmp(src, CDATA_END, sizeof(CDATA_END)-1)) {
+ if (dest + sizeof(CDATA_END_ESCAPED) < end) {
+ strcpy(dest, CDATA_END_ESCAPED);
+ src += sizeof(CDATA_END)-1;
+ dest += sizeof(CDATA_END_ESCAPED) - 1;
+ }
+ else {
+ *dest = 0;
+ return;
+ }
+ continue;
+ }
+
+ *dest = *src;
+ ++src;
+ ++dest;
+ }
+
+ // If we get here, dest was completely filled (dest == end)
+ *(dest-1) = 0;
+}
+
QT_END_NAMESPACE