summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2024-01-16 13:51:17 +0100
committerEirik Aavitsland <eirik.aavitsland@qt.io>2024-02-06 14:51:09 +0100
commitc7328d8f36710951b14c2bd7a9eff3effdb54920 (patch)
tree1f22361828946289b154ae9b7efa989110cf0d90
parentb2d9b36c15654c89f0eecabde5f2edf32ea14162 (diff)
Allow opting out of resource limits on parsing and rendering
Some checks against corrupt/crafted svgs can inhibit loading unusual but legal svg files. Add a mechanism for disabling such checks for loading trusted svgs, and implement it for the maximum limit on the number of points in an svg path element. Initially only settable by environment variable, so it can be cherry-picked to earlier branches. To be followed up with a new Option flag that can be specified on the QSvgRenderer level in new Qt versions. Fixes: QTBUG-120653 Pick-to: 6.7 6.6 6.5 Change-Id: I1c1a3f31373d6f6e6ba288bb7c907ccb6f0b3611 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/svg/qsvghandler.cpp16
-rw-r--r--src/svg/qsvghandler_p.h1
2 files changed, 12 insertions, 5 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 8aa6328..046ca1e 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -143,7 +143,7 @@ bool qsvg_get_hex_rgb(const QChar *str, int len, QRgb *rgb)
// ======== end of qcolor_p duplicate
-static bool parsePathDataFast(QStringView data, QPainterPath &path);
+static bool parsePathDataFast(QStringView data, QPainterPath &path, bool limitLength = true);
static inline QString someId(const QXmlStreamAttributes &attributes)
{
@@ -1586,7 +1586,7 @@ static void pathArc(QPainterPath &path,
}
}
-static bool parsePathDataFast(QStringView dataStr, QPainterPath &path)
+static bool parsePathDataFast(QStringView dataStr, QPainterPath &path, bool limitLength)
{
const int maxElementCount = 0x7fff; // Assume file corruption if more path elements than this
qreal x0 = 0, y0 = 0; // starting point
@@ -1907,7 +1907,7 @@ static bool parsePathDataFast(QStringView dataStr, QPainterPath &path)
break;
}
lastMode = pathElem.toLatin1();
- if (path.elementCount() > maxElementCount)
+ if (limitLength && path.elementCount() > maxElementCount)
ok = false;
}
}
@@ -2070,6 +2070,12 @@ QtSvg::Options QSvgHandler::options() const
return m_options;
}
+bool QSvgHandler::trustedSourceMode() const
+{
+ static const bool envAssumeTrusted = qEnvironmentVariableIsSet("QT_SVG_ASSUME_TRUSTED_SOURCE");
+ return envAssumeTrusted;
+}
+
static inline QStringList stringToList(const QString &str)
{
QStringList lst = str.split(QLatin1Char(','), Qt::SkipEmptyParts);
@@ -3638,13 +3644,13 @@ static QSvgNode *createMarkerNode(QSvgNode *parent,
static QSvgNode *createPathNode(QSvgNode *parent,
const QXmlStreamAttributes &attributes,
- QSvgHandler *)
+ QSvgHandler *handler)
{
QStringView data = attributes.value(QLatin1String("d"));
QPainterPath qpath;
qpath.setFillRule(Qt::WindingFill);
- if (!parsePathDataFast(data, qpath))
+ if (!parsePathDataFast(data, qpath, !handler->trustedSourceMode()))
qCWarning(lcSvgHandler, "Invalid path data; path truncated.");
QSvgNode *path = new QSvgPath(parent, qpath);
diff --git a/src/svg/qsvghandler_p.h b/src/svg/qsvghandler_p.h
index df5078c..2857ac0 100644
--- a/src/svg/qsvghandler_p.h
+++ b/src/svg/qsvghandler_p.h
@@ -100,6 +100,7 @@ public:
{ return m_defaultPen; }
QtSvg::Options options() const;
+ bool trustedSourceMode() const;
public:
bool startElement(const QString &localName, const QXmlStreamAttributes &attributes);