From 4db05007d72963c082f3ffdfcc7a68c1fb53c266 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 11 Jan 2022 15:01:22 +0100 Subject: Fix an assertion failure in massageAdjustedDateTime() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QDateTimeData &d it's passed is a copy that's about to be modified; before we do so, we haven't detached so its internals have a ref-count of two, contradicting an assertion in the non-const Data::operator->(); so just directly access d.d->m_timezone, since we know that spec == TimeZone implies !isShort(). Added test that triggered the assertion and now doesn't. Fixes: QTBUG-99668 Change-Id: I07321ad91be5adce524be18e4ab82eee7110dc6a Reviewed-by: MÃ¥rten Nordheim (cherry picked from commit 5d228beb520d92c985497fb43fa91d2920db6cb0) --- src/corelib/time/qdatetime.cpp | 6 +++--- tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index b80a59da6a..db803be4ab 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Copyright (C) 2021 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -4239,10 +4239,10 @@ static inline void massageAdjustedDateTime(QDateTimeData &d, QDate date, QTime t QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime; QDateTimePrivate::localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time); #if QT_CONFIG(timezone) - } else if (spec == Qt::TimeZone && d->m_timeZone.isValid()) { + } else if (spec == Qt::TimeZone && d.d->m_timeZone.isValid()) { QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime; QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), - d->m_timeZone, &status, &date, &time); + d.d->m_timeZone, &status, &date, &time); #endif // timezone } setDateTime(d, date, time); diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index d528361bb9..4f2706bd83 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -1131,6 +1131,18 @@ void tst_QDateTime::addDays() QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC); QCOMPARE(dt2.offsetFromUtc(), 60 * 60); +#if QT_CONFIG(timezone) + const QTimeZone cet("Europe/Oslo"); + if (cet.isValid()) { + dt1 = QDate(2022, 1, 10).startOfDay(cet); + dt2 = dt1.addDays(2); // QTBUG-99668: should not assert + QCOMPARE(dt2.date(), QDate(2022, 1, 12)); + QCOMPARE(dt2.time(), QTime(0, 0)); + QCOMPARE(dt2.timeSpec(), Qt::TimeZone); + QCOMPARE(dt2.timeZone(), cet); + } +#endif + // test last second of 1969 *is* valid (despite being time_t(-1)) dt1 = QDateTime(QDate(1970, 1, 1), QTime(23, 59, 59)); dt2 = dt1.addDays(-1); -- cgit v1.2.3