From 453695ec92cde195c912537c7db51972345ee81f Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 10 Nov 2021 13:39:25 +0100 Subject: [PATCH] Avoid overflow for date-time in the first (partly) representable day Computing the start of the first day's number of milliseconds since the epoch overflows, but adding enough seconds within the day would have brought us back inside the representable range. So, for days before the epoch, add a negative number of milliseconds from the end of the next day instead of a positive number of milliseconds from the (possibly unrepresentable) start of the target day. This is another a follow-up to commit 2b26dea51b26fff2ea955ad2b50c2c20194f0103 Change-Id: I2e0c68d7012db85dfe7da4a8a20ba95368178ed1 Reviewed-by: Thiago Macieira Reviewed-by: Qt CI Bot --- src/corelib/time/qtimezoneprivate_win.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp index ef89baf5fe..577c88187e 100644 --- a/src/corelib/time/qtimezoneprivate_win.cpp +++ b/src/corelib/time/qtimezoneprivate_win.cpp @@ -278,8 +278,16 @@ QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year) inline bool timeToMSecs(QDate date, QTime time, qint64 *msecs) { qint64 dayms = 0; - return mul_overflow(date.toJulianDay() - JULIAN_DAY_FOR_EPOCH, std::integral_constant(), &dayms) - || add_overflow(dayms, qint64(time.msecsSinceStartOfDay()), msecs); + qint64 daySinceEpoch = date.toJulianDay() - JULIAN_DAY_FOR_EPOCH; + qint64 msInDay = time.msecsSinceStartOfDay(); + if (daySinceEpoch < 0 && msInDay > 0) { + // In the earliest day with representable parts, take care to not + // underflow before an addition that would have fixed it. + ++daySinceEpoch; + msInDay -= MSECS_PER_DAY; + } + return mul_overflow(daySinceEpoch, std::integral_constant(), &dayms) + || add_overflow(dayms, msInDay, msecs); } qint64 calculateTransitionForYear(const SYSTEMTIME &rule, int year, int bias)