diff options
author | Mikolaj Boc <mikolaj.boc@qt.io> | 2022-06-13 15:27:14 +0200 |
---|---|---|
committer | Mikolaj Boc <mikolaj.boc@qt.io> | 2022-06-14 09:58:31 +0200 |
commit | 4698862b763c2ab1ef14335e6cf8f15b375441b3 (patch) | |
tree | 935b1e4f7263ca2db16b0a318abd9ba8761047e1 | |
parent | eb733a078b728e56bbfef7ab395a5de645aa2dd4 (diff) | |
download | qtsvg-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.cpp | 4 | ||||
-rw-r--r-- | tests/auto/qsvggenerator/tst_qsvggenerator.cpp | 62 |
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"; |