summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2022-07-06 13:52:46 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-07-14 09:14:12 +0000
commit4a0c00f96c2595816b5ad3281842d5f2e827fa66 (patch)
tree01cf821f52155e1e36b6ae71e7997f76f9d766cb
parent2dd3eb927af2b44ba7e6456d97ed2d24dde643e9 (diff)
downloadqtsvg-4a0c00f96c2595816b5ad3281842d5f2e827fa66.tar.gz
Avoid undefined behavior when painter transform goes oob
With some broken input files, we can end up with a matrix that scales or translates so far that it ends up with NaNs or Infs. This causes undefined behavior later when doing comparisons. We protect against this by checking for matrix validity after transforming and resetting the matrix if it becomes invalid. Fixes: QTBUG-101698 Change-Id: Iabc745c1e7a0c36449f14c4c6d9bc8066eaa8eac Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> (cherry picked from commit 1b5ab50692bd7df0bb044aec1f95120ae20560ad) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/svg/qsvgtinydocument.cpp11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/svg/qsvgtinydocument.cpp b/src/svg/qsvgtinydocument.cpp
index f6dacd8..49a796c 100644
--- a/src/svg/qsvgtinydocument.cpp
+++ b/src/svg/qsvgtinydocument.cpp
@@ -397,8 +397,16 @@ void QSvgTinyDocument::draw(QPainter *p, QSvgExtraStates &)
draw(p);
}
+static bool isValidMatrix(const QTransform &transform)
+{
+ qreal determinant = transform.determinant();
+ return qIsFinite(determinant);
+}
+
void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect)
{
+ QTransform oldTransform = p->worldTransform();
+
QRectF target = targetRect;
if (target.isEmpty()) {
QPaintDevice *dev = p->device();
@@ -447,6 +455,9 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
p->translate(-source.x(), -source.y());
}
}
+
+ if (!isValidMatrix(p->worldTransform()))
+ p->setWorldTransform(oldTransform);
}
QRectF QSvgTinyDocument::boundsOnElement(const QString &id) const