diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2019-12-02 12:55:31 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2019-12-06 14:46:48 +0100 |
commit | 653c1aab185fe59a523f16ffe0cf7b9173c2ff68 (patch) | |
tree | 8b440d68bfd87c2860903a04ad9a51dc3dd994ab | |
parent | 187f4428239ace0a0c5b55d582729434d6e7ec82 (diff) |
Fix handling of trailing space at the end of an ISO date-time
If milliseconds were followed by a space, the space was included in
the count of "digits" read as the fractional part; since we read (up
to) four digits (so that we round correctly if extras are given), a
harmless apce could cause scaling down by too large a power of ten.
Since QString::toInt() ignores leading space, we were also allowing
interior space at the start of the milliseconds, which we should not,
so catch that at the same time. Added tests, including one for the
rounding that's the reason for reading the extra digit, when present.
Fixes: QTBUG-80445
Change-Id: I606b29a94818a101f45c8b59a0f5d1f78893d78f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/time/qdatetime.cpp | 7 | ||||
-rw-r--r-- | tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp | 11 |
2 files changed, 17 insertions, 1 deletions
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 8de4f7caf8..84b8a63c48 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -2375,7 +2375,12 @@ static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format, if (!ok) return QTime(); if (size > 8 && (string.at(8) == QLatin1Char(',') || string.at(8) == QLatin1Char('.'))) { - const QStringRef msecStr(string.mid(9, 4)); + QStringRef msecStr(string.mid(9, 4)); + // toInt() ignores leading spaces, so catch them before calling it + if (!msecStr.isEmpty() && !msecStr.at(0).isDigit()) + return QTime(); + // We do, however, want to ignore *trailing* spaces. + msecStr = msecStr.trimmed(); int msecInt = msecStr.isEmpty() ? 0 : msecStr.toInt(&ok); if (!ok) return QTime(); diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index c628d2b241..029ca0aabd 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -2210,6 +2210,13 @@ void tst_QDateTime::fromStringDateFormat_data() << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 456)); // Test Qt::ISODate format. + QTest::newRow("trailing space") // QTBUG-80445 + << QString("2000-01-02 03:04:05.678 ") + << Qt::ISODate << QDateTime(QDate(2000, 1, 2), QTime(3, 4, 5, 678)); + QTest::newRow("space before millis") + << QString("2000-01-02 03:04:05. 678") << Qt::ISODate << QDateTime(); + + // Normal usage: QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00") << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); QTest::newRow("ISO +00:01") << QString::fromLatin1("1987-02-13T13:24:51+00:01") @@ -2233,8 +2240,12 @@ void tst_QDateTime::fromStringDateFormat_data() // No time specified - defaults to Qt::LocalTime. QTest::newRow("ISO data3") << QString::fromLatin1("2002-10-01") << Qt::ISODate << QDateTime(QDate(2002, 10, 1), QTime(0, 0, 0, 0), Qt::LocalTime); + // Excess digits in milliseconds, round correctly: QTest::newRow("ISO") << QString::fromLatin1("2005-06-28T07:57:30.0010000000Z") << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC); + QTest::newRow("ISO rounding") << QString::fromLatin1("2005-06-28T07:57:30.0015Z") + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), Qt::UTC); + // ... and accept comma as separator: QTest::newRow("ISO with comma 1") << QString::fromLatin1("2005-06-28T07:57:30,0040000000Z") << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 4), Qt::UTC); QTest::newRow("ISO with comma 2") << QString::fromLatin1("2005-06-28T07:57:30,0015Z") |