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 <fabian.kosmale@qt.io>
This commit is contained in:
parent
9ab44777d6
commit
a59e736171
@ -750,7 +750,7 @@ QPartialOrdering QMetaType::compare(const void *lhs, const void *rhs) const
|
|||||||
{
|
{
|
||||||
if (!lhs || !rhs)
|
if (!lhs || !rhs)
|
||||||
return QPartialOrdering::Unordered;
|
return QPartialOrdering::Unordered;
|
||||||
if (d_ptr->flags & QMetaType::IsPointer)
|
if (d_ptr && d_ptr->flags & QMetaType::IsPointer)
|
||||||
return threeWayCompare(*reinterpret_cast<const void * const *>(lhs),
|
return threeWayCompare(*reinterpret_cast<const void * const *>(lhs),
|
||||||
*reinterpret_cast<const void * const *>(rhs));
|
*reinterpret_cast<const void * const *>(rhs));
|
||||||
if (d_ptr && d_ptr->lessThan) {
|
if (d_ptr && d_ptr->lessThan) {
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QMetaType::Type)
|
Q_DECLARE_METATYPE(QMetaType::Type)
|
||||||
|
Q_DECLARE_METATYPE(QPartialOrdering)
|
||||||
|
|
||||||
namespace CheckTypeTraits
|
namespace CheckTypeTraits
|
||||||
{
|
{
|
||||||
@ -1346,6 +1347,58 @@ FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_COPY_FUNCTION)
|
|||||||
TypeTestFunctionGetter::get(type)();
|
TypeTestFunctionGetter::get(type)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QMetaType::selfCompare_data()
|
||||||
|
{
|
||||||
|
qRegisterMetaType<QPartialOrdering>();
|
||||||
|
QTest::addColumn<int>("type");
|
||||||
|
QTest::addColumn<QPartialOrdering>("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;
|
typedef QString CustomString;
|
||||||
Q_DECLARE_METATYPE(CustomString) //this line is useless
|
Q_DECLARE_METATYPE(CustomString) //this line is useless
|
||||||
|
|
||||||
|
@ -104,6 +104,8 @@ private slots:
|
|||||||
void typedConstruct();
|
void typedConstruct();
|
||||||
void constructCopy_data();
|
void constructCopy_data();
|
||||||
void constructCopy();
|
void constructCopy();
|
||||||
|
void selfCompare_data();
|
||||||
|
void selfCompare();
|
||||||
void typedefs();
|
void typedefs();
|
||||||
void registerType();
|
void registerType();
|
||||||
void isRegistered_data();
|
void isRegistered_data();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user