QDebug: do not trigger integer overflow when printing a QRect

QRect::width() and height() may overflow: they're only safe to call
when right-left+1 (or bottom-top+1) is representable by an `int`.
Therefore, avoiding calling them from QDebug, which is supposed to
"always work" (otherwise, it's not of great debugging help...).

QRectF does not have this issue as it stores the width directly.

Change-Id: I438dbacae42c17730afb92f05d16e3eebb161255
Pick-to: 6.9 6.8 6.5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Giuseppe D'Angelo 2025-01-27 17:36:28 +01:00
parent b5538a5a0e
commit 0f336500a0
2 changed files with 41 additions and 1 deletions

View File

@ -23,6 +23,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QRect;
namespace QtDebugUtils { namespace QtDebugUtils {
Q_CORE_EXPORT QByteArray toPrintable(const char *data, qint64 len, qsizetype maxSize); Q_CORE_EXPORT QByteArray toPrintable(const char *data, qint64 len, qsizetype maxSize);
@ -44,7 +46,15 @@ static inline void formatQSize(QDebug &debug, const Size &size)
template <class Rect> template <class Rect>
static inline void formatQRect(QDebug &debug, const Rect &rect) static inline void formatQRect(QDebug &debug, const Rect &rect)
{ {
debug << rect.x() << ',' << rect.y() << ' ' << rect.width() << 'x' << rect.height(); debug << rect.x() << ',' << rect.y() << ' ';
if constexpr (std::is_same_v<Rect, QRect>) {
// QRect may overflow. Calculate width and height in higher precision.
const qint64 w = qint64(rect.right()) - rect.left() + 1;
const qint64 h = qint64(rect.bottom()) - rect.top() + 1;
debug << w << 'x' << h;
} else {
debug << rect.width() << 'x' << rect.height();
}
} }
template <class Margins> template <class Margins>

View File

@ -162,6 +162,8 @@ private slots:
void smallRects() const; void smallRects() const;
void toRect(); void toRect();
void span(); void span();
void debug();
}; };
// Used to work around some floating point precision problems. // Used to work around some floating point precision problems.
@ -4499,5 +4501,33 @@ void tst_QRect::span()
QCOMPARE(QRect::span(QPoint( 1, 10), QPoint(9, 0)), QRect(QPoint(1, 0), QPoint( 9, 10))); QCOMPARE(QRect::span(QPoint( 1, 10), QPoint(9, 0)), QRect(QPoint(1, 0), QPoint( 9, 10)));
} }
void tst_QRect::debug()
{
QString str;
QDebug debug(&str);
debug.nospace();
str.clear();
debug << QRect();
QCOMPARE(str, "QRect(0,0 0x0)");
str.clear();
debug << QRect(10, 20, 30, 40);
QCOMPARE(str, "QRect(10,20 30x40)");
str.clear();
debug << QRect(-10, -20, 30, 40);
QCOMPARE(str, "QRect(-10,-20 30x40)");
str.clear();
debug << QRect(-10, -20, -30, -40);
QCOMPARE(str, "QRect(-10,-20 -30x-40)");
str.clear();
debug << QRect(QPoint(INT_MIN, INT_MIN), QPoint(INT_MAX, INT_MAX));
QCOMPARE(str, "QRect(-2147483648,-2147483648 4294967296x4294967296)");
}
QTEST_MAIN(tst_QRect) QTEST_MAIN(tst_QRect)
#include "tst_qrect.moc" #include "tst_qrect.moc"