summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-03-01 14:22:55 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2021-05-26 18:00:01 +0200
commit451500f8f81b562d65208141785e3b2077768576 (patch)
treea1e9b2b00566c4c12cab439d11cbcf489f546144 /tests/auto/corelib
parentfc6629b6bbe1ef3fb9cf58da32b5a0bf082caa4d (diff)
Check for overflow in QDateTime::setMSecsSinceEpoch()
When adding an offset from UTC, arithmetic may overflow. Likewise when combining a date and time (that have been offset for UTC). Also check the return from epochMSecsToLocalTime(), as it can fail; and pay attention to the status stored by setDateTime(), to notice when it hits an overflow. Fixed some tests that only passed because we neglected these checks. Extended a test to check we detect overflow in a couple of cases close to the extremes. Change-Id: I127a670302f94a07bb9b087b1b9c608b7c08785c Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp41
1 files changed, 30 insertions, 11 deletions
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
index 4342161345..6e68b4af05 100644
--- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
@@ -573,6 +573,7 @@ void tst_QDateTime::setSecsSinceEpoch()
QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
// Only testing UTC; see fromSecsSinceEpoch() for fuller test.
+ dt1.setTimeSpec(Qt::UTC);
const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000;
dt1.setSecsSinceEpoch(maxSeconds);
QVERIFY(dt1.isValid());
@@ -727,6 +728,17 @@ void tst_QDateTime::setMSecsSinceEpoch()
QDateTime reference(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC);
QCOMPARE(dt, reference.addMSecs(msecs));
+ // Tests that we correctly recognize when we fall off the extremities:
+ if (msecs == std::numeric_limits<qint64>::max()) {
+ QDateTime off(QDate(1970, 1, 1).startOfDay(Qt::OffsetFromUTC, 1));
+ off.setMSecsSinceEpoch(msecs);
+ QVERIFY(!off.isValid());
+ } else if (msecs == std::numeric_limits<qint64>::min()) {
+ QDateTime off(QDate(1970, 1, 1).startOfDay(Qt::OffsetFromUTC, -1));
+ off.setMSecsSinceEpoch(msecs);
+ QVERIFY(!off.isValid());
+ }
+
if ((localTimeType == LocalTimeAheadOfUtc && msecs == std::numeric_limits<qint64>::max())
|| (localTimeType == LocalTimeBehindUtc && msecs == std::numeric_limits<qint64>::min())) {
QDateTime curt = QDate(1970, 1, 1).startOfDay(); // initially in short-form
@@ -766,32 +778,39 @@ void tst_QDateTime::fromMSecsSinceEpoch()
QCOMPARE(dtUtc.date(), utc.date());
QCOMPARE(dtUtc.time(), utc.time());
- QCOMPARE(dtOffset, utc);
- QCOMPARE(dtOffset.offsetFromUtc(), 60*60);
- if (msecs != Bound::max()) // Offset is positive, so overflows max
+ if (msecs == Bound::max()) { // Offset is positive, so overflows max
+ QVERIFY(!dtOffset.isValid());
+ } else {
+ QCOMPARE(dtOffset, utc);
+ QCOMPARE(dtOffset.offsetFromUtc(), 60*60);
QCOMPARE(dtOffset.time(), utc.time().addMSecs(60*60*1000));
+ }
if (zoneIsCET) {
QCOMPARE(dtLocal.toLocalTime(), cet);
QCOMPARE(dtUtc.toLocalTime(), cet);
- QCOMPARE(dtOffset.toLocalTime(), cet);
+ if (msecs != Bound::max())
+ QCOMPARE(dtOffset.toLocalTime(), cet);
}
if (!localOverflow)
QCOMPARE(dtLocal.toMSecsSinceEpoch(), msecs);
QCOMPARE(dtUtc.toMSecsSinceEpoch(), msecs);
- QCOMPARE(dtOffset.toMSecsSinceEpoch(), msecs);
+ if (msecs != Bound::max())
+ QCOMPARE(dtOffset.toMSecsSinceEpoch(), msecs);
if (!localOverflow)
QCOMPARE(qint64(dtLocal.toSecsSinceEpoch()), msecs / 1000);
QCOMPARE(qint64(dtUtc.toSecsSinceEpoch()), msecs / 1000);
- QCOMPARE(qint64(dtOffset.toSecsSinceEpoch()), msecs / 1000);
+ if (msecs != Bound::max())
+ QCOMPARE(qint64(dtOffset.toSecsSinceEpoch()), msecs / 1000);
QDateTime reference(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC);
if (!localOverflow)
QCOMPARE(dtLocal, reference.addMSecs(msecs));
QCOMPARE(dtUtc, reference.addMSecs(msecs));
- QCOMPARE(dtOffset, reference.addMSecs(msecs));
+ if (msecs != Bound::max())
+ QCOMPARE(dtOffset, reference.addMSecs(msecs));
}
void tst_QDateTime::fromSecsSinceEpoch()
@@ -815,10 +834,10 @@ void tst_QDateTime::fromSecsSinceEpoch()
QVERIFY(!QDateTime::fromSecsSinceEpoch(first - 1).isValid());
// Use an offset for which .toUTC()'s return would flip the validity:
- QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds, Qt::OffsetFromUTC, 7200).isValid());
- QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, Qt::OffsetFromUTC, -7200).isValid());
- QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds, Qt::OffsetFromUTC, -7200).isValid());
- QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1, Qt::OffsetFromUTC, 7200).isValid());
+ QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds - 7200, Qt::OffsetFromUTC, 7200).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds - 7199, Qt::OffsetFromUTC, 7200).isValid());
+ QVERIFY(QDateTime::fromSecsSinceEpoch(7200 - maxSeconds, Qt::OffsetFromUTC, -7200).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(7199 - maxSeconds, Qt::OffsetFromUTC, -7200).isValid());
#if QT_CONFIG(timezone)
// As for offset, use zones each side of UTC: