Fix handling of invalid year in QDateTimeParser

Only proleptic calendars allow negative years; and year zero should be
treated as invalid unless the calendar has it.

Thanks again to Albert Astals Cid for reporting this, in IRC.
Found by oss-fuzzing of KDE's image plugins.

Change-Id: I5e808a6649bf0067ee46b61ef11ee01616fc9b41
Reviewed-by: Albert Astals Cid <aacid@kde.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2024-08-13 15:39:04 +02:00
parent 9b70a89554
commit 5d656e5085
2 changed files with 9 additions and 1 deletions

View File

@ -785,7 +785,7 @@ QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex, i
const int sectionmaxsize = sectionMaxSize(sectionIndex);
const bool negate = (sn.type == YearSection && m_text.size() > offset
&& m_text.at(offset) == u'-');
&& calendar.isProleptic() && m_text.at(offset) == u'-');
const int negativeYearOffset = negate ? 1 : 0;
QStringView sectionTextRef =
@ -948,6 +948,12 @@ QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex, i
} else {
result = ParsedSection(Intermediate, lastVal, used);
}
} else if (!lastVal && !calendar.hasYearZero()
&& (sn.type == YearSection
|| (sn.type == YearSection2Digits && currentValue.isValid()
&& currentValue.date().year() / 100 == 0))) {
// Year zero prohibited
result = ParsedSection(unfilled ? Acceptable : Invalid, lastVal, used);
} else {
result = ParsedSection(Acceptable, lastVal, used);
}

View File

@ -3277,6 +3277,8 @@ void tst_QDateTime::fromStringStringFormat_data()
<< u"2001-09-15T09:33:01.001 "_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900 << QDateTime();
QTest::newRow("invalid-month-year<min") // This used to fail an unfounded assertion.
<< u"0024:91:06 08:52:20"_s << u"yyyy:MM:dd HH:mm:ss"_s << 1900 << QDateTime();
QTest::newRow("invalid-year")
<< u"0000:11:06 08:51:20"_s << u"yyyy:MM:dd HH:mm:ss"_s << 1900 << QDateTime();
#if QT_CONFIG(timezone)
QTimeZone southBrazil("America/Sao_Paulo");
if (southBrazil.isValid()) {