Fix QMetaProperty::write so it tries to register a property type.

We can not assume that the property type is always registered, because
QVariant argument may contain an instance of a different type.

Change-Id: I4fc9593b826e13c401dbdacec4d60db36edc7102
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
bb10
Jędrzej Nowacki 2014-12-02 14:41:07 +01:00
parent c0a6a1db85
commit a2d7441b83
2 changed files with 55 additions and 2 deletions

View File

@ -3027,9 +3027,11 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
else {
typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask);
t = QMetaType::type(typeName);
if (t == QMetaType::UnknownType)
t = registerPropertyType();
if (t == QMetaType::UnknownType)
return false;
}
if (t == QMetaType::UnknownType)
return false;
if (t != QMetaType::QVariant && t != (uint)value.userType() && (t < QMetaType::User && !v.convert((QVariant::Type)t)))
return false;
}

View File

@ -52,6 +52,7 @@ private slots:
void isConstant();
void isFinal();
void gadget();
void readAndWriteWithLazyRegistration();
public:
enum EnumType { EnumType1 };
@ -131,6 +132,56 @@ void tst_QMetaProperty::gadget()
}
}
struct CustomReadObject : QObject
{
Q_OBJECT
};
struct CustomWriteObject : QObject
{
Q_OBJECT
};
struct CustomWriteObjectChild : CustomWriteObject
{
Q_OBJECT
};
struct TypeLazyRegistration : QObject
{
Q_OBJECT
Q_PROPERTY(CustomReadObject *read MEMBER _read)
Q_PROPERTY(CustomWriteObject *write MEMBER _write)
CustomReadObject *_read;
CustomWriteObject *_write;
public:
TypeLazyRegistration()
: _read()
, _write()
{}
};
void tst_QMetaProperty::readAndWriteWithLazyRegistration()
{
QCOMPARE(QMetaType::type("CustomReadObject*"), int(QMetaType::UnknownType));
QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType));
TypeLazyRegistration o;
QVERIFY(o.property("read").isValid());
QVERIFY(QMetaType::type("CustomReadObject*") != QMetaType::UnknownType);
QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType));
CustomWriteObjectChild data;
QVariant value = QVariant::fromValue(&data); // this register CustomWriteObjectChild
// check if base classes are not registered automatically, otherwise this test would be meaningless
QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType));
QVERIFY(o.setProperty("write", value));
QVERIFY(QMetaType::type("CustomWriteObject*") != QMetaType::UnknownType);
QCOMPARE(o.property("write").value<CustomWriteObjectChild*>(), &data);
}
QTEST_MAIN(tst_QMetaProperty)
#include "tst_qmetaproperty.moc"