summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2022-03-23 14:25:09 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2022-03-25 17:04:37 +0100
commit845eabb3145982320dce205ebd5bb034e66dfbc8 (patch)
tree1d990a961b6a6278fc91aa9763b03a5a33a4cf1f /src
parent57742f7728cc7cc017dd4fe1e5c6f7bec7cce40f (diff)
Fix ICU's handling of last representable transition
ICU's search for next transition, when the result would lie later than is representable by qint64, returns the last transition before the bound, even if this is at the time it was meant to exclude from the range searched. This lead to infinite looping when we tried to traverse transitions forward. Recognize when this happens and return the invalid data object that indicates falling off the end of time instead. Task-number: QTBUG-99747 Pick-to: 6.3 6.2 Change-Id: I1a210fb7a4086b2fdb052b2260c800bfc29f965a Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/time/qtimezoneprivate_icu.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/corelib/time/qtimezoneprivate_icu.cpp b/src/corelib/time/qtimezoneprivate_icu.cpp
index 798f231219..b1de236fcb 100644
--- a/src/corelib/time/qtimezoneprivate_icu.cpp
+++ b/src/corelib/time/qtimezoneprivate_icu.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -207,6 +207,14 @@ static QTimeZonePrivate::Data ucalTimeZoneTransition(UCalendar *m_ucal,
status = U_ZERO_ERROR;
bool ok = ucal_getTimeZoneTransitionDate(ucal, type, &tranMSecs, &status);
+ // Catch a known violation (in ICU 67) of the specified behavior:
+ if (U_SUCCESS(status) && ok && type == UCAL_TZ_TRANSITION_NEXT) {
+ // At the end of time, that can "succeed" with tranMSecs ==
+ // atMSecsSinceEpoch, which should be treated as a failure.
+ // (At the start of time, previous correctly fails.)
+ ok = qint64(tranMSecs) > atMSecsSinceEpoch;
+ }
+
// Set the transition time to find the offsets for
if (U_SUCCESS(status) && ok) {
status = U_ZERO_ERROR;