diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2017-01-04 13:43:44 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-01-20 17:49:44 +0000 |
commit | 69c576badfc1a3d33422dbe74ac575594e378c30 (patch) | |
tree | 38ce4506f1d8889cfdfbf010e73e003f3badd0b0 /src | |
parent | a8ddacaaac8054aa5eceaeca4676a29db41f1586 (diff) |
Fix UB (signed integer overflows) in QProgressBar
The expression 'minimum - 1' invokes UB when 'minimum == INT_MIN'.
Likewise, the expression 'maximum - minimum' invokes UB when
'qint64(maximum) - minimum > INT_MAX'.
Fix by restructuring the code or else by using 64-bit arithmetic.
Change-Id: I352eafa72f28ae907f41c8f88abcf0a81705c718
Task-number: QTBUG-57857
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit f4d3c87f0caab71f15e12f0f376f94a3e90a8adf)
Diffstat (limited to 'src')
-rw-r--r-- | src/widgets/widgets/qprogressbar.cpp | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp index c1c08d9ec7..53a4b6ed28 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -138,16 +138,17 @@ bool QProgressBarPrivate::repaintRequired() const if (value == lastPaintedValue) return false; - int valueDifference = qAbs(value - lastPaintedValue); - + const qint64 valueDifference = qAbs(qint64(value) - lastPaintedValue); // Check if the text needs to be repainted if (value == minimum || value == maximum) return true; + + const qint64 totalSteps = qint64(maximum) - minimum; if (textVisible) { if ((format.contains(QLatin1String("%v")))) return true; if ((format.contains(QLatin1String("%p")) - && valueDifference >= qAbs((maximum - minimum) / 100))) + && valueDifference >= qAbs(totalSteps / 100))) return true; } @@ -160,7 +161,7 @@ bool QProgressBarPrivate::repaintRequired() const // (valueDifference / (maximum - minimum) > cw / groove.width()) // transformed to avoid integer division. int grooveBlock = (q->orientation() == Qt::Horizontal) ? groove.width() : groove.height(); - return (valueDifference * grooveBlock > cw * (maximum - minimum)); + return valueDifference * grooveBlock > cw * totalSteps; } /*! @@ -254,9 +255,10 @@ QProgressBar::~QProgressBar() void QProgressBar::reset() { Q_D(QProgressBar); - d->value = d->minimum - 1; if (d->minimum == INT_MIN) d->value = INT_MIN; + else + d->value = d->minimum - 1; repaint(); } @@ -352,7 +354,7 @@ void QProgressBar::setRange(int minimum, int maximum) d->minimum = minimum; d->maximum = qMax(minimum, maximum); - if (d->value < (d->minimum - 1) || d->value > d->maximum) + if (d->value < qint64(d->minimum) - 1 || d->value > d->maximum) reset(); else update(); |