diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2021-03-17 15:04:05 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2021-04-20 16:04:14 +0200 |
commit | 855f8a3f98f366b26eecba556cdfb2e509081a29 (patch) | |
tree | b07747ff9e22db67695610843fae524fefd36912 /src/corelib/time/qdatetime.cpp | |
parent | 4dccdd3693d69fe7030e61ba9b7639c6fc76b97e (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.cpp | 43 |
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 |