summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2021-07-07 10:09:58 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-07-14 08:54:05 +0000
commitb9f40224d11f5d5e638891893b3c614a2a6dd96d (patch)
treec2dce85b4a332dc9fb103d8ba1fc76aba11408f9
parent26a9147ce2be2f78532968f69cb2b8df8b314c8e (diff)
downloadqtsvg-b9f40224d11f5d5e638891893b3c614a2a6dd96d.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) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/svg/qsvghandler.cpp19
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp14
2 files changed, 30 insertions, 3 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 65ec90f..2ad13b4 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -725,15 +725,25 @@ static QList<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;
@@ -1599,8 +1609,11 @@ static bool parsePathDataFast(QStringView dataStr, QPainterPath &path)
++str;
QChar endc = *end;
*const_cast<QChar *>(end) = u'\0'; // parseNumbersArray requires 0-termination that QStringView 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 e27ee51..e368444 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();
@@ -1051,6 +1052,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[] = {