diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2024-01-16 13:51:17 +0100 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2024-02-06 14:51:09 +0100 |
commit | c7328d8f36710951b14c2bd7a9eff3effdb54920 (patch) | |
tree | 1f22361828946289b154ae9b7efa989110cf0d90 | |
parent | b2d9b36c15654c89f0eecabde5f2edf32ea14162 (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.cpp | 16 | ||||
-rw-r--r-- | src/svg/qsvghandler_p.h | 1 |
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); |