Fix QMetaObject::newInstance on non-QObject meta object

QMetaObject::newInstance returns a QObject, thus it's not possible to
create a new instance of a Q_GADGET using this function. Previously, we
returned a non-null QObject pointer for such scenarios, which then
leads to crashes when one tries to use it. Now, we check whether the
meta object inherits QObject's meta object, and error out early
otherwise.

Change-Id: I7b1fb6c8d48b3e98161894be2f281a491963345e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Milian Wolff 2019-04-09 13:38:06 +02:00
parent 6d4a456a28
commit 5f2afe18cc
2 changed files with 19 additions and 0 deletions

View File

@ -235,6 +235,12 @@ QObject *QMetaObject::newInstance(QGenericArgument val0,
QGenericArgument val8,
QGenericArgument val9) const
{
if (!inherits(&QObject::staticMetaObject))
{
qWarning("QMetaObject::newInstance: type %s does not inherit QObject", className());
return nullptr;
}
QByteArray constructorName = className();
{
int idx = constructorName.lastIndexOf(':');

View File

@ -40,6 +40,13 @@ struct MyStruct
int i;
};
class MyGadget
{
Q_GADGET
public:
Q_INVOKABLE MyGadget() {}
};
namespace MyNamespace {
// Used in tst_QMetaObject::checkScope
class MyClass : public QObject
@ -1207,6 +1214,12 @@ void tst_QMetaObject::invokeMetaConstructor()
QCOMPARE(obj2->parent(), (QObject*)&obj);
QVERIFY(qobject_cast<NamespaceWithConstructibleClass::ConstructibleClass*>(obj2) != 0);
}
// gadget shouldn't return a valid pointer
{
QCOMPARE(MyGadget::staticMetaObject.constructorCount(), 1);
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::newInstance: type MyGadget does not inherit QObject");
QVERIFY(!MyGadget::staticMetaObject.newInstance());
}
}
void tst_QMetaObject::invokeTypedefTypes()