From 2a53017df488b3cedbfbf5a56bf105b9fc5392fa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Apr 2020 14:00:05 -0300 Subject: [PATCH] QCborValue: add an extra check against producing invalid ISO dates By QCborValue design, we store the textual representation in ISO format, equivalent of CBOR tag 0, which isn't allowed to have negative years or beyond year 10000. Change-Id: Ibdc95e9af7bd456a94ecfffd16060ccff359c296 Reviewed-by: Ulf Hermann --- src/corelib/serialization/qcborvalue.cpp | 10 ++++++---- .../serialization/qcborvalue/tst_qcborvalue.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index f5cccf1be18..30bfa367edb 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -810,10 +810,12 @@ static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d) } if (dt.isValid()) { QByteArray text = dt.toString(Qt::ISODateWithMs).toLatin1(); - replaceByteData(text, text.size(), Element::StringIsAscii); - e.type = QCborValue::String; - d->elements[0].value = qint64(QCborKnownTags::DateTimeString); - return QCborValue::DateTime; + if (!text.isEmpty()) { + replaceByteData(text, text.size(), Element::StringIsAscii); + e.type = QCborValue::String; + d->elements[0].value = qint64(QCborKnownTags::DateTimeString); + return QCborValue::DateTime; + } } break; } diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 0b3046fbdc7..d035ca4ee54 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -1970,6 +1970,21 @@ void tst_QCborValue::extendedTypeValidation_data() << encode(0xc1, 0xfb, -fplimit) << QCborValue(QCborKnownTags::UnixTime_t, -fplimit); } + + // But in fact, QCborValue stores date/times as their ISO textual + // representation, which means it can't represent dates before year 1 or + // after year 9999. + { + QDateTime dt(QDate(-1, 1, 1), QTime(0, 0), Qt::UTC); + QTest::newRow("UnixTime_t:negative-year") + << encode(0xc1, 0x3b, quint64(-dt.toSecsSinceEpoch()) - 1) + << QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch()); + + dt.setDate(QDate(10000, 1, 1)); + QTest::newRow("UnixTime_t:year10k") + << encode(0xc1, 0x1b, quint64(dt.toSecsSinceEpoch())) + << QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch()); + } } void tst_QCborValue::extendedTypeValidation()