summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2023-03-15 17:19:14 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2023-03-20 23:09:51 +0100
commit41c561ddde6210651c60c0789d592f79d7b3e4d5 (patch)
treea2c3590fee4713df7284cd023de2341e78b5ac0c /src
parent0cefeb259350938fddb123ef46a9407aa70d51a9 (diff)
Recognize POSIX rules as valid timezone IDs for the TZ backend
The constructor, via findEntry(), does allow a POSIX rule as a valid ID, so reflect that in the implementation of isTimeZoneIdAvailable(), even though we can't sensibly enumerate all possible POSIX rules in availableTimeZoneIds(). Change-Id: I7fd21d23ce8ce40c7f423b02e18d2e8df30fb952 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/time/qtimezoneprivate_tz.cpp27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
index 960a094418..95b5894c3f 100644
--- a/src/corelib/time/qtimezoneprivate_tz.cpp
+++ b/src/corelib/time/qtimezoneprivate_tz.cpp
@@ -521,7 +521,12 @@ PosixZone PosixZone::parse(const char *&pos, const char *end)
return {std::move(name), offset};
}
-static auto validatePosixRule(const QByteArray &posixRule)
+/* Parse and check a POSIX rule.
+
+ By default a simple zone abbreviation with no offset information is accepted.
+ Set \a requireOffset to \c true to require that there be offset data present.
+*/
+static auto validatePosixRule(const QByteArray &posixRule, bool requireOffset = false)
{
// Format is described here:
// http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
@@ -533,15 +538,19 @@ static auto validatePosixRule(const QByteArray &posixRule)
return fail;
const char *begin = zoneinfo.begin();
-
- // Updates begin to point after the name and offset it parses:
- if (PosixZone::parse(begin, zoneinfo.end()).name.isEmpty())
- return fail;
+ {
+ // Updates begin to point after the name and offset it parses:
+ const auto posix = PosixZone::parse(begin, zoneinfo.end());
+ if (posix.name.isEmpty())
+ return fail;
+ if (requireOffset && !posix.hasValidOffset())
+ return fail;
+ }
if (good.hasDst) {
if (begin >= zoneinfo.end())
return fail;
- // Expect a second name and offset after the first:
+ // Expect a second name (and optional offset) after the first:
if (PosixZone::parse(begin, zoneinfo.end()).name.isEmpty())
return fail;
}
@@ -1189,7 +1198,11 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs
bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
{
- return tzZones->contains(ianaId);
+ // Allow a POSIX rule as long as it has offset data. (This needs to reject a
+ // plain abbreviation, without offset, since claiming to support such zones
+ // would prevent the custom QTimeZone constructor from accepting such a
+ // name, as it doesn't want a custom zone to over-ride a "real" one.)
+ return tzZones->contains(ianaId) || validatePosixRule(ianaId, true).isValid;
}
QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const