summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-04-06 14:12:03 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-04-07 21:52:40 +0000
commit0ae0f2bdd87ce7a24674864391d1ef04a1006672 (patch)
tree70fda736bfa2555bf632c56d244776569e349273 /src
parent3de271cdace007b01a03cd84e9f12f8d3e3d5485 (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.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp
index 232619621d..ad64528537 100644
--- a/src/corelib/time/qdatetimeparser.cpp
+++ b/src/corelib/time/qdatetimeparser.cpp
@@ -1737,6 +1737,24 @@ QDateTimeParser::findTimeZoneName(QStringRef 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());