summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Loehning <robert.loehning@qt.io>2020-07-13 20:53:11 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2020-07-15 10:29:00 +0000
commita8ed1cd03bf524072d13c66ab14da8ff1b22cde2 (patch)
treec68d6eb96153a59c52bd70b573ef517c598fd548
parent0a5f8b8744347cca1ceb0f3c384e6788c3ccdbc4 (diff)
downloadqtsvg-a8ed1cd03bf524072d13c66ab14da8ff1b22cde2.tar.gz
Fix stack overflow in dtor of QSvgTinyDocument
Add a maximum to how many unfinished elements will be parsed by QSvgHandler. Fixes: oss-fuzz-24000 Change-Id: I4cea0500d2bc503d2c509d091300dd1117170299 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 2fc2cb44b275c7c18c2db262eec443eb198b9cc6) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/svg/qsvghandler.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 14f7905..ab5f9ef 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -3633,6 +3633,10 @@ void QSvgHandler::init()
parse();
}
+// Having too many unfinished elements will cause a stack overflow
+// in the dtor of QSvgTinyDocument, see oss-fuzz issue 24000.
+static const int unfinishedElementsLimit = 2048;
+
void QSvgHandler::parse()
{
xml->setNamespaceProcessing(false);
@@ -3641,6 +3645,7 @@ void QSvgHandler::parse()
m_inStyle = false;
#endif
bool done = false;
+ int remainingUnfinishedElements = unfinishedElementsLimit;
while (!xml->atEnd() && !done) {
switch (xml->readNext()) {
case QXmlStreamReader::StartElement:
@@ -3652,7 +3657,10 @@ void QSvgHandler::parse()
// namespaceUri is empty. The only possible strategy at
// this point is to do what everyone else seems to do and
// ignore the reported namespaceUri completely.
- if (!startElement(xml->name().toString(), xml->attributes())) {
+ if (remainingUnfinishedElements
+ && startElement(xml->name().toString(), xml->attributes())) {
+ --remainingUnfinishedElements;
+ } else {
delete m_doc;
m_doc = 0;
return;
@@ -3660,6 +3668,7 @@ void QSvgHandler::parse()
break;
case QXmlStreamReader::EndElement:
endElement(xml->name());
+ ++remainingUnfinishedElements;
// if we are using somebody else's qxmlstreamreader
// we should not read until the end of the stream
done = !m_ownsReader && (xml->name() == QLatin1String("svg"));