summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikolaj Boc <mikolaj.boc@qt.io>2022-06-13 15:27:14 +0200
committerMikolaj Boc <mikolaj.boc@qt.io>2022-06-14 09:58:31 +0200
commit4698862b763c2ab1ef14335e6cf8f15b375441b3 (patch)
tree935b1e4f7263ca2db16b0a318abd9ba8761047e1
parenteb733a078b728e56bbfef7ab395a5de645aa2dd4 (diff)
downloadqtsvg-4698862b763c2ab1ef14335e6cf8f15b375441b3.tar.gz
Escape the values of title and description in the svg generator
The values for title and description are not escaped. This leads to the generation of incorrectly structured SVG documents if meaningful characters are added in the title (<, >, ', " for example). Fixes: QTBUG-104203 Change-Id: I26bc5cf31c0178352774f9c1e6f57697a671d507 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r--src/svg/qsvggenerator.cpp4
-rw-r--r--tests/auto/qsvggenerator/tst_qsvggenerator.cpp62
2 files changed, 64 insertions, 2 deletions
diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp
index 1e3f55c..f641912 100644
--- a/src/svg/qsvggenerator.cpp
+++ b/src/svg/qsvggenerator.cpp
@@ -859,11 +859,11 @@ bool QSvgPaintEngine::begin(QPaintDevice *)
" version=\"1.2\" baseProfile=\"tiny\">" << Qt::endl;
if (!d->attributes.document_title.isEmpty()) {
- *d->stream << "<title>" << d->attributes.document_title << "</title>" << Qt::endl;
+ *d->stream << "<title>" << d->attributes.document_title.toHtmlEscaped() << "</title>" << Qt::endl;
}
if (!d->attributes.document_description.isEmpty()) {
- *d->stream << "<desc>" << d->attributes.document_description << "</desc>" << Qt::endl;
+ *d->stream << "<desc>" << d->attributes.document_description.toHtmlEscaped() << "</desc>" << Qt::endl;
}
d->stream->setString(&d->defs);
diff --git a/tests/auto/qsvggenerator/tst_qsvggenerator.cpp b/tests/auto/qsvggenerator/tst_qsvggenerator.cpp
index 0a282a6..d835e4b 100644
--- a/tests/auto/qsvggenerator/tst_qsvggenerator.cpp
+++ b/tests/auto/qsvggenerator/tst_qsvggenerator.cpp
@@ -25,6 +25,8 @@ public:
private slots:
void construction();
void fileName();
+ void escapesTitle();
+ void escapesDescription();
void outputDevice();
void sizeAndViewBox();
void metric();
@@ -119,6 +121,66 @@ void tst_QSvgGenerator::fileName()
checkFile(fileName);
}
+void tst_QSvgGenerator::escapesTitle()
+{
+ QByteArray byteArray;
+ QBuffer buffer(&byteArray);
+
+ const QString titleThatNeedsToBeEscaped("<malicious>\"title\" 'oh no'");
+
+ {
+ QSvgGenerator generator;
+
+ generator.setOutputDevice(&buffer);
+ generator.setTitle(titleThatNeedsToBeEscaped);
+
+ QPainter painter(&generator);
+ painter.end();
+ }
+
+ QDomDocument generated;
+ generated.setContent(byteArray);
+
+ const auto titleElements = generated.documentElement().elementsByTagName("title");
+
+ QCOMPARE(1, titleElements.size());
+
+ const auto theOnlyTitleElement = titleElements.at(0);
+
+ QCOMPARE(1, theOnlyTitleElement.childNodes().size());
+ QCOMPARE(titleThatNeedsToBeEscaped, theOnlyTitleElement.firstChild().nodeValue());
+}
+
+void tst_QSvgGenerator::escapesDescription()
+{
+ QByteArray byteArray;
+ QBuffer buffer(&byteArray);
+
+ const QString descriptionThatNeedsToBeEscaped("<evil>\"description\" 'whoopsie!'");
+
+ {
+ QSvgGenerator generator;
+
+ generator.setOutputDevice(&buffer);
+ generator.setDescription(descriptionThatNeedsToBeEscaped);
+
+ QPainter painter(&generator);
+ painter.end();
+ }
+
+ QDomDocument generated;
+ generated.setContent(byteArray);
+
+ const auto descriptionElements = generated.documentElement().elementsByTagName("desc");
+
+ QCOMPARE(1, descriptionElements.size());
+
+ const auto theOnlyDescriptionElement = descriptionElements.at(0);
+
+ QCOMPARE(1, theOnlyDescriptionElement.childNodes().size());
+ QCOMPARE(descriptionThatNeedsToBeEscaped, theOnlyDescriptionElement.firstChild().nodeValue());
+}
+
void tst_QSvgGenerator::outputDevice()
{
QString fileName = "outputDevice_output.svg";