diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-07-18 09:17:35 +0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-07-21 08:37:34 -0700 |
commit | 6a0e59ed506ecb7d6a1bc17beedd938d36a1d26f (patch) | |
tree | d65cb75892227f468d474b666a34f5a36ca7e162 /tests/auto/corelib/kernel/qvariant | |
parent | 030923c0def8b4c08fef2e1b865f30dd7287a907 (diff) |
QVariant: Avoid crash when constructed from unsuitable metatype
If the metatype does not support copy and default construction, then it
it unsuitunsuitable for use in QMetaType. We cannot prevent users from
passing in such metatypes (as we have e.g. a ctor taking QMetaType), so
verify this in customConstruct, and make the variant invalid in that
case.
Pick-to: 6.2 6.3 6.4
Change-Id: Ib1f0149c8fb9a1cce0049fd0311980754cc85d1b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'tests/auto/corelib/kernel/qvariant')
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 520515df61..240c25ae48 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -287,6 +287,9 @@ private slots: void moveOperations(); void equalsWithoutMetaObject(); + void constructFromIncompatibleMetaType_data(); + void constructFromIncompatibleMetaType(); + private: void dataStream_data(QDataStream::Version version); void loadQVariantFromDataStream(QDataStream::Version version); @@ -5107,5 +5110,49 @@ void tst_QVariant::equalsWithoutMetaObject() QVERIFY(qobjectVariant != noMetaObjectVariant); } +class NonDefaultConstructible +{ + NonDefaultConstructible(int ) {} +}; + +struct Indestructible +{ + Indestructible() {} + Indestructible(const Indestructible &) {} + Indestructible &operator=(const Indestructible &) { return *this; } +private: + ~Indestructible() {} +}; + +void tst_QVariant::constructFromIncompatibleMetaType_data() +{ + QTest::addColumn<QMetaType>("type"); + auto addRow = [](QMetaType meta) { + QTest::newRow(meta.name()) << meta; + }; + addRow(QMetaType::fromType<void>()); + addRow(QMetaType::fromType<NonDefaultConstructible>()); + addRow(QMetaType::fromType<QObject>()); + addRow(QMetaType::fromType<Indestructible>()); +} + +void tst_QVariant::constructFromIncompatibleMetaType() +{ + QFETCH(QMetaType, type); + // in that case, we run into a different condition (size == 0), and do not warn + if (QTest::currentDataTag() != QLatin1String("void")) + QTest::ignoreMessage( + QtWarningMsg, + "QVariant: Provided metatype does not support destruction, copy and default construction"); + QVariant var(type, nullptr); + QVERIFY(!var.isValid()); + QVERIFY(!var.metaType().isValid()); + + QVariant regular(1.0); + QVERIFY(!var.canView(type)); + QVERIFY(!var.canConvert(type)); + QVERIFY(!QVariant(regular).convert(type)); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" |