diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2022-03-23 14:25:09 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2022-03-25 17:04:37 +0100 |
commit | 845eabb3145982320dce205ebd5bb034e66dfbc8 (patch) | |
tree | 1d990a961b6a6278fc91aa9763b03a5a33a4cf1f /src | |
parent | 57742f7728cc7cc017dd4fe1e5c6f7bec7cce40f (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.cpp | 10 |
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; |