summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-03-14 15:18:11 +0100
committerMarc Mutz <marc.mutz@kdab.com>2016-03-15 11:23:46 +0000
commite4c6d73f925671a9c96558293472ed213861239c (patch)
treeffa69cbf982ff7e9add120dee4fa49716215e7b5 /src/corelib
parent1dcc53f6faf53a2994c6b9fe329d35fdaf61c06e (diff)
QRect: fix UB (int overflow) in center()
QRect::center() should be defined for any QRect(x1,y1,x2,x2), INT_MIN <= x1, x2, y1, y2 <= INT_MAX because the average of two signed integers is always representable as a signed integer. But not when it's calculated as (x1+x2)/2, since that expression overflows when x1 > INT_MAX - x2. Instead of playing games with Hacker's Delight-style expressions, or use Google's patented algorithm, which requires two divisions, take advantage of the fact that int is not intmax_t and perform the calculation in the qint64 domain. The cast back to int is always well- defined since, as mentioned, the result is always representable in an int. Fix a test-case that expected a nonsensical result due to overflow. [ChangeLog][QtCore][QRect] Fixed integer overflow in center(). This fixes the result for some corner-cases like a 1x1 rectangle at (INT_MIN, INT_MIN), for which the previous implementation could return anything (due to invoking undefined behavior), but commonly returned (0, 0). Change-Id: I1a885ca6dff770327dd31655c3eb473fcfeb8878 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qrect.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h
index 59cecf9a01..a0449ae134 100644
--- a/src/corelib/tools/qrect.h
+++ b/src/corelib/tools/qrect.h
@@ -245,7 +245,7 @@ Q_DECL_CONSTEXPR inline QPoint QRect::bottomLeft() const Q_DECL_NOTHROW
{ return QPoint(x1, y2); }
Q_DECL_CONSTEXPR inline QPoint QRect::center() const Q_DECL_NOTHROW
-{ return QPoint((x1+x2)/2, (y1+y2)/2); }
+{ return QPoint(int((qint64(x1)+x2)/2), int((qint64(y1)+y2)/2)); } // cast avoids overflow on addition
Q_DECL_CONSTEXPR inline int QRect::width() const Q_DECL_NOTHROW
{ return x2 - x1 + 1; }