Fix integer overflow in QSpinBox.
Change-Id: Ic204d42fbdffc44576f7e76132bc53621e836299 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
parent
d18eb260d7
commit
efc475a996
@ -1904,7 +1904,20 @@ QVariant operator+(const QVariant &arg1, const QVariant &arg2)
|
|||||||
qWarning("QAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)",
|
qWarning("QAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)",
|
||||||
arg1.typeName(), arg2.typeName(), __FILE__, __LINE__);
|
arg1.typeName(), arg2.typeName(), __FILE__, __LINE__);
|
||||||
switch (arg1.type()) {
|
switch (arg1.type()) {
|
||||||
case QVariant::Int: ret = QVariant(arg1.toInt() + arg2.toInt()); break;
|
case QVariant::Int: {
|
||||||
|
const int int1 = arg1.toInt();
|
||||||
|
const int int2 = arg2.toInt();
|
||||||
|
if (int1 > 0 && (int2 >= INT_MAX - int1)) {
|
||||||
|
// The increment overflows
|
||||||
|
ret = QVariant(INT_MAX);
|
||||||
|
} else if (int1 < 0 && (int2 <= INT_MIN - int1)) {
|
||||||
|
// The increment underflows
|
||||||
|
ret = QVariant(INT_MIN);
|
||||||
|
} else {
|
||||||
|
ret = QVariant(int1 + int2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case QVariant::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble()); break;
|
case QVariant::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble()); break;
|
||||||
case QVariant::DateTime: {
|
case QVariant::DateTime: {
|
||||||
QDateTime a2 = arg2.toDateTime();
|
QDateTime a2 = arg2.toDateTime();
|
||||||
@ -1962,7 +1975,9 @@ QVariant operator*(const QVariant &arg1, double multiplier)
|
|||||||
QVariant ret;
|
QVariant ret;
|
||||||
|
|
||||||
switch (arg1.type()) {
|
switch (arg1.type()) {
|
||||||
case QVariant::Int: ret = QVariant((int)(arg1.toInt() * multiplier)); break;
|
case QVariant::Int:
|
||||||
|
ret = static_cast<int>(qBound<double>(INT_MIN, arg1.toInt() * multiplier, INT_MAX));
|
||||||
|
break;
|
||||||
case QVariant::Double: ret = QVariant(arg1.toDouble() * multiplier); break;
|
case QVariant::Double: ret = QVariant(arg1.toDouble() * multiplier); break;
|
||||||
case QVariant::DateTime: {
|
case QVariant::DateTime: {
|
||||||
double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier;
|
double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier;
|
||||||
|
@ -135,6 +135,8 @@ private slots:
|
|||||||
|
|
||||||
void sizeHint();
|
void sizeHint();
|
||||||
|
|
||||||
|
void integerOverflow();
|
||||||
|
|
||||||
void taskQTBUG_5008_textFromValueAndValidate();
|
void taskQTBUG_5008_textFromValueAndValidate();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@ -1014,6 +1016,35 @@ void tst_QSpinBox::taskQTBUG_5008_textFromValueAndValidate()
|
|||||||
QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value()));
|
QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QSpinBox::integerOverflow()
|
||||||
|
{
|
||||||
|
QSpinBox sb;
|
||||||
|
sb.setRange(INT_MIN, INT_MAX);
|
||||||
|
|
||||||
|
sb.setValue(INT_MAX - 1);
|
||||||
|
sb.stepUp();
|
||||||
|
QCOMPARE(sb.value(), INT_MAX);
|
||||||
|
sb.stepUp();
|
||||||
|
QCOMPARE(sb.value(), INT_MAX);
|
||||||
|
|
||||||
|
sb.setValue(INT_MIN + 1);
|
||||||
|
sb.stepDown();
|
||||||
|
QCOMPARE(sb.value(), INT_MIN);
|
||||||
|
sb.stepDown();
|
||||||
|
QCOMPARE(sb.value(), INT_MIN);
|
||||||
|
|
||||||
|
sb.setValue(0);
|
||||||
|
QCOMPARE(sb.value(), 0);
|
||||||
|
sb.setSingleStep(INT_MAX);
|
||||||
|
sb.stepUp();
|
||||||
|
QCOMPARE(sb.value(), INT_MAX);
|
||||||
|
sb.stepDown();
|
||||||
|
QCOMPARE(sb.value(), 0);
|
||||||
|
sb.stepDown();
|
||||||
|
QCOMPARE(sb.value(), INT_MIN + 1);
|
||||||
|
sb.stepDown();
|
||||||
|
QCOMPARE(sb.value(), INT_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QSpinBox)
|
QTEST_MAIN(tst_QSpinBox)
|
||||||
#include "tst_qspinbox.moc"
|
#include "tst_qspinbox.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user