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 Pick-to: 6.1 6.0 5.15 Change-Id: I83052b1b6888728c81135db22a9c6298ae439375 Reviewed-by: Robert Löhning <robert.loehning@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
89bdd09670
commit
0c9fc20e7f
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user