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 19:38:45 +0000 |
commit | 51812618e7f0486ad029f3c17bfe7baec8800d06 (patch) | |
tree | 43ccce45f1ba20247afeb415bd55e9934f4ac535 /src/corelib | |
parent | ae7aabd1b7ac9d13c2c0e8e49b94b90376257e23 (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/corelib')
-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 c64f622a57..0a8721a2b5 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -1737,6 +1737,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()); |