diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2021-07-07 10:09:58 +0200 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2021-07-16 10:36:27 +0200 |
commit | 6de64d30d4ec51b3d1bc48a1f15424f3216eb42a (patch) | |
tree | 3862b42ffd7a186bff44742a616cbc473103ad74 | |
parent | 8a2a9c9d763709f032bc82e2711dbe56a4ad4160 (diff) | |
download | qtsvg-6de64d30d4ec51b3d1bc48a1f15424f3216eb42a.tar.gz |
Fix parsing of arc elements in paths
The arc element takes some flag parameters, which could be mixed up
with the float parameters since svg does not require delimiting
characters here. Hence legal svg would be misread..
Fixes: QTBUG-92184
Change-Id: I5885c50d47e2e06ab0f02afefb7a5585c5c713ff
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
(cherry picked from commit b313862fa04d9a5403c16670a0d911eb3c633ee5)
-rw-r--r-- | src/svg/qsvghandler.cpp | 19 | ||||
-rw-r--r-- | tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 14 |
2 files changed, 30 insertions, 3 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index cf23606..daf436e 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -728,15 +728,25 @@ static QVector<qreal> parseNumbersList(const QChar *&str) return points; } -static inline void parseNumbersArray(const QChar *&str, QVarLengthArray<qreal, 8> &points) +static inline void parseNumbersArray(const QChar *&str, QVarLengthArray<qreal, 8> &points, + const char *pattern = nullptr) { + const size_t patternLen = qstrlen(pattern); while (str->isSpace()) ++str; while (isDigit(str->unicode()) || *str == QLatin1Char('-') || *str == QLatin1Char('+') || *str == QLatin1Char('.')) { - points.append(toDouble(str)); + if (patternLen && pattern[points.size() % patternLen] == 'f') { + // flag expected, may only be 0 or 1 + if (*str != QLatin1Char('0') && *str != QLatin1Char('1')) + return; + points.append(*str == QLatin1Char('0') ? 0.0 : 1.0); + ++str; + } else { + points.append(toDouble(str)); + } while (str->isSpace()) ++str; @@ -1629,8 +1639,11 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path) ++str; QChar endc = *end; *const_cast<QChar *>(end) = 0; // parseNumbersArray requires 0-termination that QStringRef cannot guarantee + const char *pattern = nullptr; + if (pathElem == QLatin1Char('a') || pathElem == QLatin1Char('A')) + pattern = "rrrffrr"; QVarLengthArray<qreal, 8> arg; - parseNumbersArray(str, arg); + parseNumbersArray(str, arg, pattern); *const_cast<QChar *>(end) = endc; if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z')) arg.append(0);//dummy diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index 8f1f03b..36c76ec 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -74,6 +74,7 @@ private slots: void fillRule(); void opacity(); void paths(); + void paths2(); void displayMode(); void strokeInherit(); void testFillInheritance(); @@ -1047,6 +1048,19 @@ void tst_QSvgRenderer::paths() } } +void tst_QSvgRenderer::paths2() +{ + const char *svg = + "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\">" + "<path d=\"M 3 8 A 5 5 0 1013 8\" id=\"path1\"/>" + "</svg>"; + + QByteArray data(svg); + QSvgRenderer renderer(data); + QVERIFY(renderer.isValid()); + QCOMPARE(renderer.boundsOnElement(QLatin1String("path1")).toRect(), QRect(3, 8, 10, 5)); +} + void tst_QSvgRenderer::displayMode() { static const char *svgs[] = { |