From a59e7361714d50687d82a2d9abae9e95825a23b6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 17 Jan 2022 09:38:22 -0800 Subject: QMetaType: add a missing check for null d_ptr Bug introduced in 6.0. This is the only unprotected d_ptr I could find. [ChangeLog][QtCore][QMetaType] Fixed a bug that would cause QMetaType::compare() and QVariant::compare() to crash on invalid meta types and variants. Pick-to: 6.2 6.3 Fixes: QTBUG-99960 Change-Id: I0e5f6bec596a4a78bd3bfffd16cb1f7b2d146688 Reviewed-by: Fabian Kosmale --- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 53 ++++++++++++++++++++++ .../auto/corelib/kernel/qmetatype/tst_qmetatype.h | 2 + 2 files changed, 55 insertions(+) (limited to 'tests/auto/corelib/kernel') diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 740dcbc9be..96c8e2a559 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -39,6 +39,7 @@ #include Q_DECLARE_METATYPE(QMetaType::Type) +Q_DECLARE_METATYPE(QPartialOrdering) namespace CheckTypeTraits { @@ -1346,6 +1347,58 @@ FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_COPY_FUNCTION) TypeTestFunctionGetter::get(type)(); } +void tst_QMetaType::selfCompare_data() +{ + qRegisterMetaType(); + QTest::addColumn("type"); + QTest::addColumn("order"); + + auto orderingFor = [](QMetaType::Type t) { + if (t == QMetaType::UnknownType || t == QMetaType::Void) + return QPartialOrdering::Unordered; + return QPartialOrdering::Equivalent; + }; + + QTest::newRow("unknown-type") << int(QMetaType::UnknownType) << orderingFor(QMetaType::UnknownType); + +#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ + QTest::newRow(QMetaType::typeName(QMetaType::MetaTypeName)) << int(QMetaType::MetaTypeName) << orderingFor(QMetaType::MetaTypeName); +FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW) +#undef ADD_METATYPE_TEST_ROW +} + +void tst_QMetaType::selfCompare() +{ + QFETCH(int, type); + QFETCH(QPartialOrdering, order); + + QMetaType t(type); + void *v1 = t.create(nullptr); + void *v2 = t.create(nullptr); + auto scope = qScopeGuard([=] { + t.destroy(v1); + t.destroy(v2); + }); + + // all these types have an equality comparator + QCOMPARE(t.equals(v1, v2), order == QPartialOrdering::Equivalent); + + if (t.iface() && t.iface()->lessThan) + QCOMPARE(t.compare(v1, v2), order); + + // for the primitive types, do a memcmp() too + switch (type) { + default: + break; + +#define ADD_METATYPE_CASE(MetaTypeName, MetaTypeId, RealType) \ + case QMetaType::MetaTypeName: +FOR_EACH_PRIMITIVE_METATYPE(ADD_METATYPE_CASE) +#undef ADD_METATYPE_CASE + QCOMPARE(memcmp(v1, v2, t.sizeOf()), 0); + } +} + typedef QString CustomString; Q_DECLARE_METATYPE(CustomString) //this line is useless diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h index b126b86475..15fe3e6874 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h @@ -104,6 +104,8 @@ private slots: void typedConstruct(); void constructCopy_data(); void constructCopy(); + void selfCompare_data(); + void selfCompare(); void typedefs(); void registerType(); void isRegistered_data(); -- cgit v1.2.3