diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 89aba9a53de..23c9ddedb25 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -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 diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index bad8837ed24..6975a4d9ced 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -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());