summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2022-08-16 20:37:53 +0300
committerTarja Sundqvist <tarja.sundqvist@qt.io>2022-08-16 20:37:53 +0300
commit58a0c41ecbb808be0135e0ceec4ad990cd2e88f4 (patch)
treec9e0f619dafff74d3d07886fb771314655bd921b
parent4f625ebfa7cb63c865141e50ff1877fca1e94142 (diff)
parent22388ac3075e6506dbeb42aa34d1207d43ad6af9 (diff)
downloadqtsvg-58a0c41ecbb808be0135e0ceec4ad990cd2e88f4.tar.gz
Merge remote-tracking branch 'origin/tqtc/lts-5.15.6' into tqtc/lts-5.15-opensourcev5.15.6-lts-lgpl
Change-Id: If8c2bd3ed78ecf1384015f3376a958ec13d502cf
-rw-r--r--.qmake.conf2
-rw-r--r--src/svg/qsvghandler.cpp93
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp14
3 files changed, 69 insertions, 40 deletions
diff --git a/.qmake.conf b/.qmake.conf
index b8e1161..53c1ac9 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -3,4 +3,4 @@ load(qt_build_config)
CONFIG += warning_clean
DEFINES += QT_NO_FOREACH
-MODULE_VERSION = 5.15.5
+MODULE_VERSION = 5.15.6
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 9dac05c..299efac 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;
@@ -1384,7 +1394,8 @@ static void parseFont(QSvgNode *node,
break;
case FontSizeValue: {
QSvgHandler::LengthType dummy; // should always be pixel size
- fontStyle->setSize(parseLength(attributes.fontSize, dummy, handler));
+ fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
+ qreal(0xffff)));
}
break;
default:
@@ -1629,8 +1640,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
@@ -2358,6 +2372,28 @@ static bool parseAnimateNode(QSvgNode *parent,
return true;
}
+static int parseClockValue(const QString &instr, bool *ok)
+{
+ QStringRef str(&instr);
+ int res = 0;
+ int ms = 1000;
+ str = str.trimmed();
+ if (str.endsWith(QLatin1String("ms"))) {
+ str.chop(2);
+ ms = 1;
+ } else if (str.endsWith(QLatin1String("s"))) {
+ str.chop(1);
+ }
+ double val = ms * toDouble(str, ok);
+ if (ok) {
+ if (val > std::numeric_limits<int>::min() && val < std::numeric_limits<int>::max())
+ res = static_cast<int>(val);
+ else
+ *ok = false;
+ }
+ return res;
+}
+
static bool parseAnimateColorNode(QSvgNode *parent,
const QXmlStreamAttributes &attributes,
QSvgHandler *handler)
@@ -2391,23 +2427,13 @@ static bool parseAnimateColorNode(QSvgNode *parent,
}
}
- int ms = 1000;
- beginStr = beginStr.trimmed();
- if (beginStr.endsWith(QLatin1String("ms"))) {
- beginStr.chop(2);
- ms = 1;
- } else if (beginStr.endsWith(QLatin1String("s"))) {
- beginStr.chop(1);
- }
- durStr = durStr.trimmed();
- if (durStr.endsWith(QLatin1String("ms"))) {
- durStr.chop(2);
- ms = 1;
- } else if (durStr.endsWith(QLatin1String("s"))) {
- durStr.chop(1);
- }
- int begin = static_cast<int>(toDouble(beginStr) * ms);
- int end = static_cast<int>((toDouble(durStr) + begin) * ms);
+ bool ok = true;
+ int begin = parseClockValue(beginStr, &ok);
+ if (!ok)
+ return false;
+ int end = begin + parseClockValue(durStr, &ok);
+ if (!ok || end <= begin)
+ return false;
QSvgAnimateColor *anim = new QSvgAnimateColor(begin, end, 0);
anim->setArgs((targetStr == QLatin1String("fill")), colors);
@@ -2497,24 +2523,13 @@ static bool parseAnimateTransformNode(QSvgNode *parent,
}
}
- int ms = 1000;
- beginStr = beginStr.trimmed();
- if (beginStr.endsWith(QLatin1String("ms"))) {
- beginStr.chop(2);
- ms = 1;
- } else if (beginStr.endsWith(QLatin1String("s"))) {
- beginStr.chop(1);
- }
- int begin = static_cast<int>(toDouble(beginStr) * ms);
- durStr = durStr.trimmed();
- if (durStr.endsWith(QLatin1String("ms"))) {
- durStr.chop(2);
- ms = 1;
- } else if (durStr.endsWith(QLatin1String("s"))) {
- durStr.chop(1);
- ms = 1000;
- }
- int end = static_cast<int>(toDouble(durStr)*ms) + begin;
+ bool ok = true;
+ int begin = parseClockValue(beginStr, &ok);
+ if (!ok)
+ return false;
+ int end = begin + parseClockValue(durStr, &ok);
+ if (!ok || end <= begin)
+ return false;
QSvgAnimateTransform::TransformType type = QSvgAnimateTransform::Empty;
if (typeStr == QLatin1String("translate")) {
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[] = {