Return early if qt_mapFillRect will return empty QRect

Credit to OSS-Fuzz, this fixes issue 406541912. When rendering the svg
image from that report, an integer overflow happend while calculating a
QRect which is empty anyway. To avoid that, return an empty, default
constructed QRect instead of calculating further.

Picking back to 6.5 which is the oldest maintained version which
contains this function.

Pick-to: 6.8 6.5
Change-Id: I1a0d1310c55f7be613a6292f36481ac7c7e5b56f
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit d1b88f8b73c16e1ee362fa4cc853bcaadae0df6a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Robert Löhning 2025-03-31 23:13:05 +02:00 committed by Qt Cherry-pick Bot
parent 5cafb9c760
commit 7a8baa2583
2 changed files with 23 additions and 0 deletions

View File

@ -34,6 +34,10 @@ inline QRect qt_mapFillRect(const QRectF &rect, const QTransform &xf)
// as that can sometimes be slightly off around the .5 point, leading to wrong rounding
QPoint pt1 = xf.map(rect.topLeft()).toPoint();
QPoint pt2 = xf.map(rect.bottomRight()).toPoint();
// cut short if the result will be an empty QRect anyway
// side effect: avoids overflows in the calculations below
if (Q_UNLIKELY(pt1.x() == pt2.x() || pt1.y() == pt2.y()))
return QRect();
// Normalize and adjust for the QRect vs. QRectF bottomright
return QRect::span(pt1, pt2).adjusted(0, 0, -1, -1);
}

View File

@ -1741,6 +1741,25 @@ void tst_QPainter::setClipRect()
p.setClipRect(QRectF(10.5, 10.5, 10.5, -10.5));
QVERIFY(p.clipRegion().isEmpty());
}
// extreme transform, values reverse-engineered from oss-fuzz issue 406541912
// crashed with a failed assert due to an integer overflow
{
QPainter p(&img);
p.setTransform(QTransform(37.7, 0., 0.,
0., 233., 0.,
18.85, -163099999883.5, 1.));
p.setClipRect(QRect(0, 0, 10, 1), Qt::ReplaceClip);
}
// the same extreme transform, edited to overflow on the x-axis instead
{
QPainter p(&img);
p.setTransform(QTransform(233., 0., 0.,
0., 37.7, 0.,
-163099999883.5, 18.85, 1.));
p.setClipRect(QRect(0, 0, 1, 10), Qt::ReplaceClip);
}
}
/*