QML: Check result when constructing object from metaobject

If you pass insufficient arguments to call the ctor, the resulting
object is null and cannot be used.

Fixes: QTBUG-114910
Change-Id: Ib184684b6a7665bcdc1a3fe8f8a2401a33a8ac1c
Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 3110117bfa)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Ulf Hermann 2023-07-05 13:12:01 +02:00 committed by Qt Cherry-pick Bot
parent bca9e06ac3
commit ad529b77f2
2 changed files with 28 additions and 3 deletions

View File

@ -2781,9 +2781,11 @@ ReturnedValue QMetaObjectWrapper::constructInternal(const Value *argv, int argc)
objectOrGadget, d()->constructors, d()->constructorCount, v4, callData)) {
object = CallPrecise(objectOrGadget, *ctor, v4, callData, QMetaObject::CreateInstance);
}
Scoped<QMetaObjectWrapper> metaObject(scope, this);
object->defineDefaultProperty(v4->id_constructor(), metaObject);
object->setPrototypeOf(const_cast<QMetaObjectWrapper*>(this));
if (object) {
Scoped<QMetaObjectWrapper> metaObject(scope, this);
object->defineDefaultProperty(v4->id_constructor(), metaObject);
object->setPrototypeOf(const_cast<QMetaObjectWrapper*>(this));
}
return object.asReturnedValue();
}

View File

@ -1043,6 +1043,17 @@ private:
int m_called = 1;
};
class TestQMetaObject2 : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE TestQMetaObject2(int a) : m_called(a) {}
int called() const { return m_called; }
private:
int m_called = 1;
};
void tst_QJSEngine::newQObjectPropertyCache()
{
QScopedPointer<QObject> obj(new QObject);
@ -1118,6 +1129,18 @@ void tst_QJSEngine::newQMetaObject() {
QCOMPARE(metaObject.property("C").toInt(), 2);
}
{
QJSEngine engine;
const QJSValue metaObject = engine.newQMetaObject(&TestQMetaObject2::staticMetaObject);
engine.globalObject().setProperty("Example"_L1, metaObject);
const QJSValue invalid = engine.evaluate("new Example()"_L1);
QVERIFY(invalid.isError());
QCOMPARE(invalid.toString(), "Error: Insufficient arguments"_L1);
const QJSValue valid = engine.evaluate("new Example(123)"_L1);
QCOMPARE(qjsvalue_cast<TestQMetaObject2 *>(valid)->called(), 123);
}
}
void tst_QJSEngine::exceptionInSlot()