summaryrefslogtreecommitdiffstats
path: root/src/corelib/time/qdatetime.cpp
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-03-17 15:04:05 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2021-04-20 16:04:14 +0200
commit855f8a3f98f366b26eecba556cdfb2e509081a29 (patch)
treeb07747ff9e22db67695610843fae524fefd36912 /src/corelib/time/qdatetime.cpp
parent4dccdd3693d69fe7030e61ba9b7639c6fc76b97e (diff)
Handle overflow in QTimeZonePrivate::dataForLocalTime() and its caller
If the final result is outside the representable range, we can only declare the given date-time invalid. Change-Id: Ibce09462048bf351199657a5da2c55bb3ce5b934 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/time/qdatetime.cpp')
-rw-r--r--src/corelib/time/qdatetime.cpp43
1 files changed, 25 insertions, 18 deletions
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index d61bd3a69b..f627836a46 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -3255,26 +3255,33 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
Q_ASSERT(zone.isValid());
// Get the effective data from QTimeZone
QTimeZonePrivate::Data data = zone.d->dataForLocalTime(zoneMSecs, int(hint));
- Q_ASSERT(zone.d->offsetFromUtc(data.atMSecsSinceEpoch) == data.offsetFromUtc);
- Q_ASSERT(([data](qint64 offset) {
- return offset == data.offsetFromUtc
- // When zoneMSecs falls in a spring-forward's gap:
- || offset == data.standardTimeOffset
- // When it falls in the gap leading into double-DST:
- || offset == 2 * data.standardTimeOffset
- // When it falls in a skipped day (Pacific date-line crossings):
- || (data.offsetFromUtc - offset) % SECS_PER_DAY == 0;
- })((zoneMSecs - data.atMSecsSinceEpoch) / MSECS_PER_SEC));
- // Docs state any time before 1970-01-01 will *not* have any DST applied
- // but all affected times afterwards will have DST applied.
- if (data.atMSecsSinceEpoch < 0) {
- msecsToTime(zoneMSecs, zoneDate, zoneTime);
- return zoneMSecs - data.standardTimeOffset * MSECS_PER_SEC;
+ if (data.offsetFromUtc == QTimeZonePrivate::invalidSeconds()) {
+ if (zoneDate)
+ *zoneDate = QDate();
+ if (zoneTime)
+ *zoneTime = QTime();
} else {
- msecsToTime(data.atMSecsSinceEpoch + data.offsetFromUtc * MSECS_PER_SEC,
- zoneDate, zoneTime);
- return data.atMSecsSinceEpoch;
+ Q_ASSERT(zone.d->offsetFromUtc(data.atMSecsSinceEpoch) == data.offsetFromUtc);
+ Q_ASSERT(([data](qint64 offset) {
+ return offset == data.offsetFromUtc
+ // When zoneMSecs falls in a spring-forward's gap:
+ || offset == data.standardTimeOffset
+ // When it falls in the gap leading into double-DST:
+ || offset == 2 * data.standardTimeOffset
+ // When it falls in a skipped day (Pacific date-line crossings):
+ || (data.offsetFromUtc - offset) % SECS_PER_DAY == 0;
+ })((zoneMSecs - data.atMSecsSinceEpoch) / MSECS_PER_SEC));
+ // Docs state any time before 1970-01-01 will *not* have any DST applied
+ // but all affected times afterwards will have DST applied.
+ if (data.atMSecsSinceEpoch < 0) {
+ msecsToTime(zoneMSecs, zoneDate, zoneTime);
+ return zoneMSecs - data.standardTimeOffset * MSECS_PER_SEC;
+ } else {
+ msecsToTime(data.atMSecsSinceEpoch + data.offsetFromUtc * MSECS_PER_SEC,
+ zoneDate, zoneTime);
+ }
}
+ return data.atMSecsSinceEpoch;
}
#endif // timezone