diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2020-09-07 14:48:57 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2020-10-09 01:11:00 +0200 |
commit | 2a6f2fe9ef9a5d0755443ba94183d97b2fac1a28 (patch) | |
tree | 0306fe462f93f293f94b9869749c775dce3744ca /tests | |
parent | cb0ecd6b6dfaea372d7973e4d78e661deb441540 (diff) |
Check against {und,ov}erflow in more QDateTime methods
QDateTime's range of possible values is wider than anyone generally
needs, but let's not do confusing things when someone does overflow
it.
Change-Id: Ifbaf7a0f02cd3afe7d3d13c829bf0887eba29f7f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index d66ee5c832..9d80583e72 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -564,6 +564,19 @@ void tst_QDateTime::setSecsSinceEpoch() QCOMPARE(dt1, QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36), Qt::UTC)); QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC); QCOMPARE(dt1.offsetFromUtc(), 60 * 60); + + // Only testing UTC; see fromSecsSinceEpoch() for fuller test. + const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000; + dt1.setSecsSinceEpoch(maxSeconds); + QVERIFY(dt1.isValid()); + dt1.setSecsSinceEpoch(-maxSeconds); + QVERIFY(dt1.isValid()); + dt1.setSecsSinceEpoch(maxSeconds + 1); + QVERIFY(!dt1.isValid()); + dt1.setSecsSinceEpoch(0); + QVERIFY(dt1.isValid()); + dt1.setSecsSinceEpoch(-maxSeconds - 1); + QVERIFY(!dt1.isValid()); } void tst_QDateTime::setMSecsSinceEpoch_data() @@ -754,6 +767,7 @@ void tst_QDateTime::fromMSecsSinceEpoch() void tst_QDateTime::fromSecsSinceEpoch() { + // Compare setSecsSinceEpoch() const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000; const QDateTime early = QDateTime::fromSecsSinceEpoch(-maxSeconds, Qt::UTC); const QDateTime late = QDateTime::fromSecsSinceEpoch(maxSeconds, Qt::UTC); @@ -1204,7 +1218,7 @@ void tst_QDateTime::addYears() QCOMPARE(end.offsetFromUtc(), 60 * 60); } -void tst_QDateTime::addSecs_data() +void tst_QDateTime::addMSecs_data() { QTest::addColumn<QDateTime>("dt"); QTest::addColumn<qint64>("nsecs"); @@ -1300,6 +1314,31 @@ void tst_QDateTime::addSecs_data() QTest::newRow("epoch-1s-local") << QDateTime(QDate(1970, 1, 1), QTime(0, 0)) << qint64(-1) << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59)); + + // Overflow and Underflow + const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000; + QTest::newRow("after-last") + << QDateTime::fromSecsSinceEpoch(maxSeconds, Qt::UTC) << qint64(1) << QDateTime(); + QTest::newRow("to-last") + << QDateTime::fromSecsSinceEpoch(maxSeconds - 1, Qt::UTC) << qint64(1) + << QDateTime::fromSecsSinceEpoch(maxSeconds, Qt::UTC); + QTest::newRow("before-first") + << QDateTime::fromSecsSinceEpoch(-maxSeconds, Qt::UTC) << qint64(-1) << QDateTime(); + QTest::newRow("to-first") + << QDateTime::fromSecsSinceEpoch(1 - maxSeconds, Qt::UTC) << qint64(-1) + << QDateTime::fromSecsSinceEpoch(-maxSeconds, Qt::UTC); +} + +void tst_QDateTime::addSecs_data() +{ + addMSecs_data(); + + const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000; + // Results would be representable, but the step isn't + QTest::newRow("leap-up") + << QDateTime::fromSecsSinceEpoch(-1, Qt::UTC) << 1 + maxSeconds << QDateTime(); + QTest::newRow("leap-down") + << QDateTime::fromSecsSinceEpoch(1, Qt::UTC) << -1 - maxSeconds << QDateTime(); } void tst_QDateTime::addSecs() @@ -1308,16 +1347,15 @@ void tst_QDateTime::addSecs() QFETCH(const qint64, nsecs); QFETCH(const QDateTime, result); QDateTime test = dt.addSecs(nsecs); - QCOMPARE(test, result); - QCOMPARE(test.timeSpec(), dt.timeSpec()); - if (test.timeSpec() == Qt::OffsetFromUTC) - QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc()); - QCOMPARE(result.addSecs(-nsecs), dt); -} - -void tst_QDateTime::addMSecs_data() -{ - addSecs_data(); + if (!result.isValid()) { + QVERIFY(!test.isValid()); + } else { + QCOMPARE(test, result); + QCOMPARE(test.timeSpec(), dt.timeSpec()); + if (test.timeSpec() == Qt::OffsetFromUTC) + QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc()); + QCOMPARE(result.addSecs(-nsecs), dt); + } } void tst_QDateTime::addMSecs() @@ -1327,11 +1365,15 @@ void tst_QDateTime::addMSecs() QFETCH(const QDateTime, result); QDateTime test = dt.addMSecs(qint64(nsecs) * 1000); - QCOMPARE(test, result); - QCOMPARE(test.timeSpec(), dt.timeSpec()); - if (test.timeSpec() == Qt::OffsetFromUTC) - QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc()); - QCOMPARE(result.addMSecs(qint64(-nsecs) * 1000), dt); + if (!result.isValid()) { + QVERIFY(!test.isValid()); + } else { + QCOMPARE(test, result); + QCOMPARE(test.timeSpec(), dt.timeSpec()); + if (test.timeSpec() == Qt::OffsetFromUTC) + QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc()); + QCOMPARE(result.addMSecs(qint64(-nsecs) * 1000), dt); + } } void tst_QDateTime::toTimeSpec_data() @@ -1540,7 +1582,7 @@ void tst_QDateTime::secsTo() QFETCH(const qint64, nsecs); QFETCH(const QDateTime, result); - if (dt.isValid()) { + if (result.isValid()) { QCOMPARE(dt.secsTo(result), (qint64)nsecs); QCOMPARE(result.secsTo(dt), (qint64)-nsecs); QVERIFY((dt == result) == (0 == nsecs)); @@ -1566,7 +1608,7 @@ void tst_QDateTime::msecsTo() QFETCH(const qint64, nsecs); QFETCH(const QDateTime, result); - if (dt.isValid()) { + if (result.isValid()) { QCOMPARE(dt.msecsTo(result), qint64(nsecs) * 1000); QCOMPARE(result.msecsTo(dt), -qint64(nsecs) * 1000); QVERIFY((dt == result) == (0 == (qint64(nsecs) * 1000))); |