diff --git a/src/gui/painting/qmath_p.h b/src/gui/painting/qmath_p.h index d4e5be8339b..d4a74af5c56 100644 --- a/src/gui/painting/qmath_p.h +++ b/src/gui/painting/qmath_p.h @@ -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); } diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 9ef5c6f34e1..575b4bb70a0 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -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); + } } /*