118 lines
5.0 KiB
Diff
118 lines
5.0 KiB
Diff
From 08c5ae85586ef9ef6b3f80f98f367de48c6db3d0 Mon Sep 17 00:00:00 2001
|
|
From: Thiago Macieira <thiago.macieira@intel.com>
|
|
Date: Wed, 02 Sep 2026 12:04:25 -0300
|
|
Subject: [PATCH] JSON/CBOR: fix crash converting an empty URL tag to JSON
|
|
|
|
A CBOR URL (tag 32) wrapping an empty, definite-length text string has
|
|
no backing ByteData after decoding via QCborValue::fromCbor(), so
|
|
byteData() returns nullptr. convertExtendedTypeToJson() dereferenced it
|
|
unconditionally and crashed. Guard against the null pointer.
|
|
|
|
Fixes: QTBUG-149841
|
|
Change-Id: I919b870f7a23d41fdb98fffde1fa84247d5c2d18
|
|
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
|
|
(cherry picked from commit 9e9988ee57c0210a5ba57435182b094f50b50f28)
|
|
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
|
(cherry picked from commit a2cd9d2a70575c37153d43e9c5396a9144af1923)
|
|
Reviewed-by: Akseli Salovaara <akseli.salovaara@qt.io>
|
|
---
|
|
|
|
diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp
|
|
index 4093719..f35c127 100644
|
|
--- a/src/corelib/serialization/qjsoncbor.cpp
|
|
+++ b/src/corelib/serialization/qjsoncbor.cpp
|
|
@@ -174,15 +174,21 @@
|
|
qint64 tag = d->elements.at(0).value;
|
|
|
|
switch (tag) {
|
|
- case qint64(QCborKnownTags::Url):
|
|
+ case qint64(QCborKnownTags::Url): {
|
|
#ifdef QT_BOOTSTRAPPED
|
|
break;
|
|
#else
|
|
// use the fully-encoded URL form
|
|
- if (d->elements.at(1).type == QCborValue::String)
|
|
- return QUrl::fromEncoded(d->byteData(1)->asByteArrayView()).toString(QUrl::FullyEncoded);
|
|
+ Element e = d->elements.at(1);
|
|
+ const ByteData *bd = d->byteData(e);
|
|
+ if (e.type == QCborValue::String) {
|
|
+ if (!bd)
|
|
+ return QString();
|
|
+ return QUrl::fromEncoded(bd->asByteArrayView()).toString(QUrl::FullyEncoded);
|
|
+ }
|
|
Q_FALLTHROUGH();
|
|
#endif
|
|
+ }
|
|
|
|
case qint64(QCborKnownTags::DateTimeString):
|
|
case qint64(QCborKnownTags::ExpectedBase64url):
|
|
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
|
|
index c7b9b3b..e56622f 100644
|
|
--- a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
|
|
+++ b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
|
|
@@ -51,8 +51,13 @@
|
|
return QTest::addRow("Double:%g", exp.toDouble());
|
|
if (v.type() == QCborValue::ByteArray || v.type() == QCborValue::String)
|
|
return QTest::addRow("%s:%zd", typeString, size_t(exp.toString().size()));
|
|
- if (v.type() >= 0x10000)
|
|
+ if (v.type() == QCborValue::Uuid)
|
|
return QTest::newRow(exp.typeName());
|
|
+ if (v.type() >= 0x10000) {
|
|
+ // all others are based on string
|
|
+ return QTest::addRow("%s:%zd", exp.typeName(),
|
|
+ size_t(v.taggedValue().toString().size()));
|
|
+ }
|
|
return QTest::newRow(typeString);
|
|
};
|
|
addRow() << v << exp << json;
|
|
@@ -75,10 +80,15 @@
|
|
add(std::numeric_limits<qint64>::min(), std::numeric_limits<qint64>::min(), std::numeric_limits<qint64>::min());
|
|
|
|
// converts to string in JSON:
|
|
+ add(QByteArray(), QByteArray(), QString());
|
|
add(QByteArray("Hello"), QByteArray("Hello"), "SGVsbG8");
|
|
+ // Invalid datetimes are not QCborValue::DateTime
|
|
+ //add(QCborValue(QDateTime()), QString(), QString());
|
|
add(QCborValue(dt), dt, dt.toString(Qt::ISODateWithMs));
|
|
+ add(QCborValue(QUrl()), QUrl(), QString());
|
|
add(QCborValue(QUrl("http://example.com/{q}")), QUrl("http://example.com/{q}"),
|
|
"http://example.com/%7Bq%7D"); // note the encoded form in JSON
|
|
+ add(QCborValue(QRegularExpression()), QRegularExpression(), QString());
|
|
add(QCborValue(QRegularExpression(".")), QRegularExpression("."), ".");
|
|
add(QCborValue(uuid), uuid, uuid.toString(QUuid::WithoutBraces));
|
|
|
|
@@ -116,6 +126,7 @@
|
|
}
|
|
|
|
QCOMPARE(v.toVariant(), variant);
|
|
+
|
|
if (variant.isValid()) {
|
|
QVariant variant2 = QVariant::fromValue(v);
|
|
QVERIFY(variant2.canConvert(variant.metaType()));
|
|
@@ -123,6 +134,12 @@
|
|
QCOMPARE(variant2, variant);
|
|
}
|
|
|
|
+#if QT_CONFIG(cborstreamreader) && QT_CONFIG(cborstreamwriter)
|
|
+ // repeat after a round-trip through CBOR encoding, which exercises the
|
|
+ // decoding paths in QCborValue::fromCbor()
|
|
+ QCOMPARE(QCborValue::fromCbor(v.toCbor()).toVariant(), variant);
|
|
+#endif
|
|
+
|
|
// tags get ignored:
|
|
QCOMPARE(QCborValue(QCborKnownTags::Signature, v).toVariant(), variant);
|
|
|
|
@@ -147,6 +164,12 @@
|
|
QCOMPARE(v.toJsonValue(), json);
|
|
QCOMPARE(QVariant::fromValue(v).toJsonValue(), json);
|
|
|
|
+#if QT_CONFIG(cborstreamreader) && QT_CONFIG(cborstreamwriter)
|
|
+ // repeat after a round-trip through CBOR encoding, which exercises the
|
|
+ // decoding paths in QCborValue::fromCbor()
|
|
+ QCOMPARE(QCborValue::fromCbor(v.toCbor()).toJsonValue(), json);
|
|
+#endif
|
|
+
|
|
// most tags get ignored:
|
|
QCOMPARE(QCborValue(QCborKnownTags::Signature, v).toJsonValue(), json);
|
|
|