summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qtimezoneprivate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qtimezoneprivate.cpp')
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp56
1 files changed, 34 insertions, 22 deletions
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index 4286119586..7eacb1f716 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -44,6 +44,7 @@
#include "qtimezoneprivate_p.h"
#include "qtimezoneprivate_data_p.h"
+#include <qdatastream.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -446,32 +447,43 @@ QTimeZone::OffsetData QTimeZonePrivate::toOffsetData(const QTimeZonePrivate::Dat
bool QTimeZonePrivate::isValidId(const QByteArray &ianaId)
{
// Rules for defining TZ/IANA names as per ftp://ftp.iana.org/tz/code/Theory
- // * Use only valid POSIX file name components
- // * Within a file name component, use only ASCII letters, `.', `-' and `_'.
- // * Do not use digits
- // * A file name component must not exceed 14 characters or start with `-'
- // Aliases such as "Etc/GMT+7" and "SystemV/EST5EDT" are valid so we need to accept digits
- if (ianaId.contains(' '))
- return false;
- QList<QByteArray> parts = ianaId.split('/');
- foreach (const QByteArray &part, parts) {
- if (part.size() > 14 || part.size() < 1)
- return false;
- if (part.at(0) == '-')
- return false;
- for (int i = 0; i < part.size(); ++i) {
- QChar ch = part.at(i);
- if (!(ch >= 'a' && ch <= 'z')
+ // 1. Use only valid POSIX file name components
+ // 2. Within a file name component, use only ASCII letters, `.', `-' and `_'.
+ // 3. Do not use digits
+ // 4. A file name component must not exceed 14 characters or start with `-'
+ // Aliases such as "Etc/GMT+7" and "SystemV/EST5EDT" are valid so we need to accept digits, ':', and '+'.
+
+ // The following would be preferable if QRegExp would work on QByteArrays directly:
+ // const QRegExp rx(QStringLiteral("[a-z0-9:+._][a-z0-9:+._-]{,13}(?:/[a-z0-9:+._][a-z0-9:+._-]{,13})*"),
+ // Qt::CaseInsensitive);
+ // return rx.exactMatch(ianaId);
+
+ // hand-rolled version:
+ const int MinSectionLength = 1;
+ const int MaxSectionLength = 14;
+ int sectionLength = 0;
+ for (const char *it = ianaId.begin(), * const end = ianaId.end(); it != end; ++it, ++sectionLength) {
+ const char ch = *it;
+ if (ch == '/') {
+ if (sectionLength < MinSectionLength || sectionLength > MaxSectionLength)
+ return false; // violates (4)
+ sectionLength = -1;
+ } else if (ch == '-') {
+ if (sectionLength == 0)
+ return false; // violates (4)
+ } else if (!(ch >= 'a' && ch <= 'z')
&& !(ch >= 'A' && ch <= 'Z')
&& !(ch == '_')
&& !(ch >= '0' && ch <= '9')
&& !(ch == '-')
&& !(ch == '+')
&& !(ch == ':')
- && !(ch == '.'))
- return false;
+ && !(ch == '.')) {
+ return false; // violates (2)
}
}
+ if (sectionLength < MinSectionLength || sectionLength > MaxSectionLength)
+ return false; // violates (4)
return true;
}
@@ -558,8 +570,8 @@ template<> QTimeZonePrivate *QSharedDataPointer<QTimeZonePrivate>::clone()
// Create default UTC time zone
QUtcTimeZonePrivate::QUtcTimeZonePrivate()
{
- const QString name = QStringLiteral("UTC");
- init(QByteArrayLiteral("UTC"), 0, name, name, QLocale::AnyCountry, name);
+ const QString name = utcQString();
+ init(utcQByteArray(), 0, name, name, QLocale::AnyCountry, name);
}
// Create a named UTC time zone
@@ -583,7 +595,7 @@ QUtcTimeZonePrivate::QUtcTimeZonePrivate(qint32 offsetSeconds)
QString utcId;
if (offsetSeconds == 0)
- utcId = QStringLiteral("UTC");
+ utcId = utcQString();
else
utcId = isoOffsetFormat(offsetSeconds);
@@ -675,7 +687,7 @@ qint32 QUtcTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
QByteArray QUtcTimeZonePrivate::systemTimeZoneId() const
{
- return QByteArrayLiteral("UTC");
+ return utcQByteArray();
}
QSet<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const