From a3a7d485fa2d572225c7050badf28784316aec37 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 30 Sep 2015 23:27:20 +0200 Subject: Fix crash in QMetaProperty::write for custom types and conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if t >= QMetaType::User, we would not return false nor call convert. We would then pass a pointer to whatever is in the QVariant to the qt_metacall that is expecting a pointer to an object of a different type. Since we have custom converters, we can call QVarent::convert even for custom types anyway. [ChangeLog][QtCore] Fixed crash when setting a QVariant of a different type to a property of a custom type. Attempt to do a conversion instead. Task-number: QTBUG-40644 Change-Id: Ib6fbd7e7ddcf25c5ee247ea04177e079f6d7de35 Reviewed-by: Jędrzej Nowacki --- .../kernel/qmetaproperty/tst_qmetaproperty.cpp | 45 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'tests/auto/corelib/kernel') diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp index 4d54aa4dc8..10656a0dcd 100644 --- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp +++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2014 Olivier Goffart +** Copyright (C) 2015 Olivier Goffart ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -38,15 +38,29 @@ #include #include +struct CustomType +{ + int padding; + QString str; + CustomType(const QString &str = QString()) : str(str) {} + operator QString() const { return str; } + friend bool operator!=(const CustomType &a, const CustomType &b) + { return a.str != b.str; } +}; + +Q_DECLARE_METATYPE(CustomType) + class tst_QMetaProperty : public QObject { Q_OBJECT Q_PROPERTY(EnumType value WRITE setValue READ getValue) Q_PROPERTY(EnumType value2 WRITE set_value READ get_value) + Q_PROPERTY(QString value7 MEMBER value7) Q_PROPERTY(int value8 READ value8) Q_PROPERTY(int value9 READ value9 CONSTANT) Q_PROPERTY(int value10 READ value10 FINAL) Q_PROPERTY(QMap map MEMBER map) + Q_PROPERTY(CustomType custom MEMBER custom) private slots: void hasStdCppSet(); @@ -55,6 +69,7 @@ private slots: void gadget(); void readAndWriteWithLazyRegistration(); void mapProperty(); + void conversion(); public: enum EnumType { EnumType1 }; @@ -68,7 +83,9 @@ public: int value9() const { return 1; } int value10() const { return 1; } + QString value7; QMap map; + CustomType custom; }; void tst_QMetaProperty::hasStdCppSet() @@ -195,5 +212,31 @@ void tst_QMetaProperty::mapProperty() QCOMPARE(map, (v.value >())); } +void tst_QMetaProperty::conversion() +{ + QMetaType::registerConverter(); + QMetaType::registerConverter(); + + QString hello = QStringLiteral("Hello"); + + // Write to a QString property using a CustomType in a QVariant + QMetaProperty value7P = metaObject()->property(metaObject()->indexOfProperty("value7")); + QVERIFY(value7P.isValid()); + QVERIFY(value7P.write(this, QVariant::fromValue(CustomType(hello)))); + QCOMPARE(value7, hello); + + // Write to a CustomType property using a QString in a QVariant + QMetaProperty customP = metaObject()->property(metaObject()->indexOfProperty("custom")); + QVERIFY(customP.isValid()); + QVERIFY(customP.write(this, hello)); + QCOMPARE(custom.str, hello); + + // Something that cannot be converted should fail + QVERIFY(!customP.write(this, 45)); + QVERIFY(!customP.write(this, QVariant::fromValue(this))); + QVERIFY(!value7P.write(this, QVariant::fromValue(this))); + QVERIFY(!value7P.write(this, QVariant::fromValue(this))); +} + QTEST_MAIN(tst_QMetaProperty) #include "tst_qmetaproperty.moc" -- cgit v1.2.3