diff options
author | Hatem ElKharashy <hatem.elkharashy@qt.io> | 2024-02-05 16:13:25 +0200 |
---|---|---|
committer | Hatem ElKharashy <hatem.elkharashy@qt.io> | 2024-02-06 13:19:40 +0200 |
commit | b2d9b36c15654c89f0eecabde5f2edf32ea14162 (patch) | |
tree | 7e5955a1ed245391fa1917d6aa61d77f1587648e | |
parent | 96f8357d5e68fdf00d0ae1a4561ba56727615f2d (diff) |
Skip parsing nested svg element
The SVG Tiny 1.2 does not allow nested svg elements in an SVG Document.
With the current implementation, the parser will create more than one
QSvgTinyDocument class, and it will stop parsing the SVG file at a wrong
position, because the done flag does not cover this case.
Fixes: QTBUG-121981
Change-Id: Idbba6524c6acbad20946cfe47f4f812ce6e11d23
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r-- | src/svg/qsvghandler.cpp | 23 | ||||
-rw-r--r-- | src/svg/qsvghandler_p.h | 3 |
2 files changed, 19 insertions, 7 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index f28ba55..8aa6328 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -4536,9 +4536,8 @@ void QSvgHandler::parse() } break; case QXmlStreamReader::EndElement: - endElement(xml->name()); + done = endElement(xml->name()); ++remainingUnfinishedElements; - done = (xml->name() == QLatin1String("svg")); break; case QXmlStreamReader::Characters: characters(xml->text()); @@ -4588,6 +4587,15 @@ bool QSvgHandler::startElement(const QString &localName, if (!m_doc && localName != QLatin1String("svg")) return false; + if (m_doc && localName == QLatin1String("svg")) { + m_skipNodes.push(Doc); + qCWarning(lcSvgHandler) << "Skipping a nested svg element, because " + "SVG Document must not contain nested svg elements in Svg Tiny 1.2"; + } + + if (!m_skipNodes.isEmpty() && m_skipNodes.top() == Doc) + return true; + if (FactoryMethod method = findGroupFactory(localName, options())) { //group node = method(m_doc ? m_nodes.top() : 0, attributes, this); @@ -4746,14 +4754,17 @@ bool QSvgHandler::startElement(const QString &localName, bool QSvgHandler::endElement(const QStringView localName) { CurrentNode node = m_skipNodes.top(); + + if (node == Doc && localName != QLatin1String("svg")) + return false; + m_skipNodes.pop(); m_whitespaceMode.pop(); popColor(); - if (node == Unknown) { - return true; - } + if (node == Unknown) + return false; #ifdef QT_NO_CSSPARSER Q_UNUSED(localName); @@ -4767,7 +4778,7 @@ bool QSvgHandler::endElement(const QStringView localName) else if (m_style && !m_skipNodes.isEmpty() && m_skipNodes.top() != Style) m_style = 0; - return true; + return ((localName == QLatin1String("svg")) && (node != Doc)); } void QSvgHandler::resolvePaintServers(QSvgNode *node, int nestedDepth) diff --git a/src/svg/qsvghandler_p.h b/src/svg/qsvghandler_p.h index 045014d..df5078c 100644 --- a/src/svg/qsvghandler_p.h +++ b/src/svg/qsvghandler_p.h @@ -120,7 +120,8 @@ private: { Unknown, Graphics, - Style + Style, + Doc }; QStack<CurrentNode> m_skipNodes; |