diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2021-04-06 14:12:03 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-04-07 20:32:09 +0000 |
commit | cc3cb77f62ddbd4667c7ad51e9c5c8718dd53b1b (patch) | |
tree | 6085e8f1a3663226769b329a02ebafdf71d3565c /src | |
parent | ae71de40b802a6017a2a04e667929bcbd2a2805d (diff) |
Avoid attempting to parse insanely long texts as zone names
There are limits on zone name length and the trial-and-error approach
we're more or less forced to take to parsing gets horribly expensive
if applied to every prefix of a very long string. So apply a loosened
version of the zone-name validity rule that limits the length of the
fragments between slashes and limit the number of such fragments.
Fixes: QTBUG-92275
Change-Id: I83052b1b6888728c81135db22a9c6298ae439375
Reviewed-by: Robert Löhning <robert.loehning@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 0c9fc20e7ff7b4ff0f15e0b2c071ea834625dce9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/time/qdatetimeparser.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index a36eded2e5..7bee5a68b1 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -1740,6 +1740,24 @@ QDateTimeParser::findTimeZoneName(QStringView str, const QDateTime &when) const int index = std::distance(str.cbegin(), std::find_if(str.cbegin(), str.cend(), invalidZoneNameCharacter)); + // Limit name fragments (between slashes) to 20 characters. + // (Valid time-zone IDs are allowed up to 14 and Android has quirks up to 17.) + // Limit number of fragments to six; no known zone name has more than four. + int lastSlash = -1; + int count = 0; + Q_ASSERT(index <= str.size()); + while (lastSlash < index) { + int slash = str.indexOf(QLatin1Char('/'), lastSlash + 1); + if (slash < 0) + slash = index; // i.e. the end of the candidate text + else if (++count > 5) + index = slash; // Truncate + if (slash - lastSlash > 20) + index = lastSlash + 20; // Truncate + // If any of those conditions was met, index <= slash, so this exits the loop: + lastSlash = slash; + } + for (; index > systemLength; --index) { // Find longest match str.truncate(index); QTimeZone zone(str.toLatin1()); |