From e325bd68fd6bdcbcb0c4e7478cb6371b60d89905 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 23 Apr 2020 16:03:59 +0200 Subject: Catch overflow in QDateTime::fromSecsSinceEpoch() It's documented to be undefined if the number of seconds is outside the allowed range, but it doesn't hurt for that undefined behavior to happen to be that the result is invalid. Added a simple test. Change-Id: I20c3f680c7948b3904f213452272133be77e4d62 Reviewed-by: Andrei Golubev Reviewed-by: Thiago Macieira --- .../auto/corelib/time/qdatetime/tst_qdatetime.cpp | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tests/auto/corelib/time') diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index 2e45460544..bf84508522 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -73,6 +73,7 @@ private slots: void setSecsSinceEpoch(); void setMSecsSinceEpoch_data(); void setMSecsSinceEpoch(); + void fromSecsSinceEpoch(); void fromMSecsSinceEpoch_data(); void fromMSecsSinceEpoch(); void toString_isoDate_data(); @@ -790,6 +791,36 @@ void tst_QDateTime::fromMSecsSinceEpoch() QCOMPARE(dtOffset, reference.addMSecs(msecs)); } +void tst_QDateTime::fromSecsSinceEpoch() +{ + const qint64 maxSeconds = std::numeric_limits::max() / 1000; + + QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds).isValid()); + QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1).isValid()); + QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds).isValid()); + QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1).isValid()); + + QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds, Qt::UTC).isValid()); + QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, Qt::UTC).isValid()); + QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds, Qt::UTC).isValid()); + QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1, Qt::UTC).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()); + +#if QT_CONFIG(timezone) + // As for offset, use zones each side of UTC: + const QTimeZone west("UTC-02:00"), east("UTC+02:00"); + QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds, east).isValid()); + QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, west).isValid()); + QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds, west).isValid()); + QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1, east).isValid()); +#endif // timezone +} + void tst_QDateTime::toString_isoDate_data() { QTest::addColumn("datetime"); -- cgit v1.2.3