diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2017-01-04 13:43:44 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2017-01-06 16:20:26 +0000 |
commit | f4d3c87f0caab71f15e12f0f376f94a3e90a8adf (patch) | |
tree | 63f864d5776749c3461a97503678d066de506286 /src/widgets | |
parent | fb85a72325d7954592ac88bbe82c913ae6124424 (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>
Diffstat (limited to 'src/widgets')
-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 10f005e6d3..2893849c42 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -144,16 +144,17 @@ bool QProgressBarPrivate::repaintRequired() const if (value == lastPaintedValue) return false; - int valueDifference = qAbs(value - lastPaintedValue); - + const auto valueDifference = qAbs(qint64(value) - lastPaintedValue); // Check if the text needs to be repainted if (value == minimum || value == maximum) return true; + + const auto 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; } @@ -166,7 +167,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; } /*! @@ -260,9 +261,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(); } @@ -358,7 +360,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(); |