Address problems with date-time parsing near bounds
Document the limited range of datetimes that can be parsed from strings and the (awkward) consequence of the range bounds being specified in local time. Add tests for UTC hitting those bounds and QEXPECT_FAIL() the ones that (as the new docs say they may) fail. Technically the fact that the UTC:min one *doesn't* fail is evidence of a bug in the existing date-time parser. Its replacement should support unbounded parsing. Pick to 6.8 required removing a QEXPECT_FAIL() specific (on MS) to the std::chrono::tzdb backend, which isn't present before 6.9. Fixes: QTBUG-129287 Task-number: QTBUG-77948 Pick-to: 6.5 Change-Id: Ic90558f1a06a62f7d0a947e37802370d1ab4e373 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 3e25203d4d5ba428309e972367dbdf99c4e70327)
This commit is contained in:
parent
037e14dd07
commit
4408d077ac
@ -5883,7 +5883,11 @@ QDateTime QDateTime::fromString(QStringView string, Qt::DateFormat format)
|
||||
two digits.
|
||||
|
||||
Incorrectly specified fields of the \a string will cause an invalid
|
||||
QDateTime to be returned.
|
||||
QDateTime to be returned. Only datetimes between the local time start of
|
||||
year 100 and end of year 9999 are supported. Note that datetimes near the
|
||||
ends of this range in other time-zones, notably including UTC, may fall
|
||||
outside the range (and thust be treated as invalid) depending on local time
|
||||
zone.
|
||||
|
||||
\note Day and month names as well as AM/PM indicators must be given in
|
||||
English (C locale). If localized month and day names or localized forms of
|
||||
|
@ -3334,6 +3334,17 @@ void tst_QDateTime::fromStringStringFormat_data()
|
||||
QTest::newRow("ASN.1:UTC-end")
|
||||
<< u"491231235959Z"_s << u"yyMMddHHmmsst"_s << 1950
|
||||
<< QDate(2049, 12, 31).endOfDay(QTimeZone::UTC).addMSecs(-999);
|
||||
// Reproducer for QTBUG-129287
|
||||
QTest::newRow("ASN.1:max")
|
||||
<< u"99991231235959Z"_s << u"yyyyMMddHHmmsst"_s << 1950
|
||||
<< QDate(9999, 12, 31).endOfDay(QTimeZone::UTC).addMSecs(-999);
|
||||
// Can also be reproduced with more legible formats:
|
||||
QTest::newRow("UTC:max")
|
||||
<< u"9999 Dec 31 23:59:59 +00:00"_s << u"yyyy MMM dd HH:mm:ss t"_s << 9900
|
||||
<< QDate(9999, 12, 31).endOfDay(QTimeZone::UTC).addMSecs(-999);
|
||||
QTest::newRow("UTC:min")
|
||||
<< u"0100 Jan 1 00:00:00 +00:00"_s << u"yyyy MMM d HH:mm:ss t"_s << 100
|
||||
<< QDate(100, 1, 1).startOfDay(QTimeZone::UTC);
|
||||
|
||||
// fuzzer test
|
||||
QTest::newRow("integer overflow found by fuzzer")
|
||||
@ -3359,9 +3370,17 @@ void tst_QDateTime::fromStringStringFormat()
|
||||
QFETCH(int, baseYear);
|
||||
QFETCH(QDateTime, expected);
|
||||
|
||||
QDateTime dt = QDateTime::fromString(string, format, baseYear);
|
||||
if (futureTimeType == LocalTimeAheadOfUtc) {
|
||||
// The new parser should remove the bounds, removing this limitation.
|
||||
QEXPECT_FAIL("ASN.1:max", "QTBUG-77948: min/max are local times", Abort);
|
||||
QEXPECT_FAIL("UTC:max", "QTBUG-77948: min/max are local times", Abort);
|
||||
}
|
||||
// For contrast, UTC::min gets away with it, which probably means there are
|
||||
// genuinely out-of-range cases the old parser gets wrong.
|
||||
|
||||
QDateTime dt = QDateTime::fromString(string, format, baseYear);
|
||||
QCOMPARE(dt, expected);
|
||||
|
||||
if (expected.isValid()) {
|
||||
QCOMPARE(dt.timeSpec(), expected.timeSpec());
|
||||
QCOMPARE(dt.timeRepresentation(), dt.timeRepresentation());
|
||||
|
Loading…
x
Reference in New Issue
Block a user