summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/svg/qsvggraphics.cpp23
-rw-r--r--src/svg/qsvggraphics_p.h1
-rw-r--r--src/svg/qsvghandler.cpp14
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp10
4 files changed, 32 insertions, 16 deletions
diff --git a/src/svg/qsvggraphics.cpp b/src/svg/qsvggraphics.cpp
index 12f2349..bcd2452 100644
--- a/src/svg/qsvggraphics.cpp
+++ b/src/svg/qsvggraphics.cpp
@@ -41,11 +41,12 @@
#include "qsvgfont_p.h"
-#include "qpainter.h"
-#include "qtextdocument.h"
-#include "qabstracttextdocumentlayout.h"
-#include "qtextcursor.h"
-#include "qdebug.h"
+#include <qabstracttextdocumentlayout.h>
+#include <qdebug.h>
+#include <qpainter.h>
+#include <qscopedvaluerollback.h>
+#include <qtextcursor.h>
+#include <qtextdocument.h>
#include <math.h>
#include <limits.h>
@@ -458,14 +459,14 @@ void QSvgText::addText(const QString &text)
}
QSvgUse::QSvgUse(const QPointF &start, QSvgNode *parent, QSvgNode *node)
- : QSvgNode(parent), m_link(node), m_start(start)
+ : QSvgNode(parent), m_link(node), m_start(start), m_recursing(false)
{
}
void QSvgUse::draw(QPainter *p, QSvgExtraStates &states)
{
- if (Q_UNLIKELY(!m_link || isDescendantOf(m_link)))
+ if (Q_UNLIKELY(!m_link || isDescendantOf(m_link) || m_recursing))
return;
applyStyle(p, states);
@@ -473,7 +474,10 @@ void QSvgUse::draw(QPainter *p, QSvgExtraStates &states)
if (!m_start.isNull()) {
p->translate(m_start);
}
- m_link->draw(p, states);
+ {
+ QScopedValueRollback<bool> guard(m_recursing, true);
+ m_link->draw(p, states);
+ }
if (!m_start.isNull()) {
p->translate(-m_start);
}
@@ -556,7 +560,8 @@ QSvgNode::Type QSvgVideo::type() const
QRectF QSvgUse::bounds(QPainter *p, QSvgExtraStates &states) const
{
QRectF bounds;
- if (Q_LIKELY(m_link && !isDescendantOf(m_link))) {
+ if (Q_LIKELY(m_link && !isDescendantOf(m_link) && !m_recursing)) {
+ QScopedValueRollback<bool> guard(m_recursing, true);
p->translate(m_start);
bounds = m_link->transformedBounds(p, states);
p->translate(-m_start);
diff --git a/src/svg/qsvggraphics_p.h b/src/svg/qsvggraphics_p.h
index 1138d1a..8488b33 100644
--- a/src/svg/qsvggraphics_p.h
+++ b/src/svg/qsvggraphics_p.h
@@ -251,6 +251,7 @@ private:
QSvgNode *m_link;
QPointF m_start;
QString m_linkId;
+ mutable bool m_recursing;
};
class QSvgVideo : public QSvgNode
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index d30cf9f..fe79977 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -2615,17 +2615,17 @@ static QSvgStyleProperty *createFontNode(QSvgNode *parent,
parent = parent->parent();
}
- if (parent) {
+ if (parent && !myId.isEmpty()) {
QSvgTinyDocument *doc = static_cast<QSvgTinyDocument*>(parent);
- QSvgFont *font = new QSvgFont(horizAdvX);
- font->setFamilyName(myId);
- if (!font->familyName().isEmpty()) {
- if (!doc->svgFont(font->familyName()))
- doc->addSvgFont(font);
+ QSvgFont *font = doc->svgFont(myId);
+ if (!font) {
+ font = new QSvgFont(horizAdvX);
+ font->setFamilyName(myId);
+ doc->addSvgFont(font);
}
return new QSvgFontStyle(font, doc);
}
- return 0;
+ return nullptr;
}
static bool parseFontFaceNode(QSvgStyleProperty *parent,
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index aa07554..e0646f2 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -1423,6 +1423,16 @@ void tst_QSvgRenderer::testUseElement()
" <circle fill=\"#a6ce39\" cx=\"0\" cy=\"0\" r=\"33\" />"
" </g>"
" </defs>"
+ "</svg>",
+ // 17 - Indirect self referral
+ "<svg>"
+ " <defs>"
+ " <g id=\"g0\">"
+ " <g id=\"g1\"><use href=\"#g2\"/></g>"
+ " <g id=\"g2\"><use href=\"#g1\"/></g>"
+ " </g>"
+ " </defs>"
+ " <use xlink:href=\"#g0\" fill=\"black\"/>"
"</svg>"
};