Fix crash in QQmlObjectCreator::populateInstance
If we cannot create the attached properties object, we need to generate an error and return early. The attached properties are unavailable then. Pick-to: 6.2 6.3 Fixes: QTBUG-101401 Change-Id: I92539ba577b435675f812c4a2bdbbbfd1de65ecf Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
01f6ba9949
commit
25eca6b7cf
|
@ -758,6 +758,13 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
|
|||
}
|
||||
QObject *qmlObject = qmlAttachedPropertiesObject(
|
||||
_qobject, attachedType.attachedPropertiesFunction(QQmlEnginePrivate::get(engine)));
|
||||
if (!qmlObject) {
|
||||
recordError(binding->location,
|
||||
QStringLiteral("Could not create attached properties object '%1'")
|
||||
.arg(QString::fromUtf8(attachedType.typeName())));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject,
|
||||
/*value type property*/ nullptr, binding))
|
||||
return false;
|
||||
|
@ -1493,6 +1500,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
|
|||
const QQmlPropertyData *valueTypeProperty,
|
||||
const QV4::CompiledData::Binding *binding)
|
||||
{
|
||||
Q_ASSERT(instance);
|
||||
QQmlData *declarativeData = QQmlData::get(instance, /*create*/true);
|
||||
|
||||
qSwap(_qobject, instance);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import QtQml
|
||||
import ABC
|
||||
|
||||
QtObject {
|
||||
id: testItem
|
||||
objectName: "00000000000000000000"
|
||||
ItemAttached.attachedName: "111111111"
|
||||
}
|
|
@ -1984,6 +1984,41 @@ private:
|
|||
int m_nothing = 12;
|
||||
};
|
||||
|
||||
class ItemAttached : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString attachedName READ attachedName WRITE setAttachedName NOTIFY attachedNameChanged)
|
||||
QML_ELEMENT
|
||||
QML_ATTACHED(ItemAttached)
|
||||
public:
|
||||
ItemAttached(QObject *parent = nullptr) : QObject(parent) {}
|
||||
|
||||
QString attachedName() const { return m_name; }
|
||||
void setAttachedName(const QString &name)
|
||||
{
|
||||
if (name != m_name) {
|
||||
m_name = name;
|
||||
emit attachedNameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
static ItemAttached *qmlAttachedProperties(QObject *object)
|
||||
{
|
||||
if (object->objectName() != QLatin1String("foo")) {
|
||||
qWarning("Only foo can have ItemAttached!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ItemAttached(object);
|
||||
}
|
||||
|
||||
signals:
|
||||
void attachedNameChanged();
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
};
|
||||
|
||||
void registerTypes();
|
||||
|
||||
#endif // TESTTYPES_H
|
||||
|
|
|
@ -396,6 +396,7 @@ private slots:
|
|||
void customValueTypes();
|
||||
void valueTypeList();
|
||||
void componentMix();
|
||||
void uncreatableAttached();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
|
@ -6935,6 +6936,20 @@ void tst_qqmllanguage::componentMix()
|
|||
QCOMPARE(delegate2->metaObject(), &QQmlComponent::staticMetaObject);
|
||||
}
|
||||
|
||||
void tst_qqmllanguage::uncreatableAttached()
|
||||
{
|
||||
qmlRegisterTypesAndRevisions<ItemAttached>("ABC", 1);
|
||||
QQmlEngine engine;
|
||||
const QUrl url = testFileUrl("uncreatableAttached.qml");
|
||||
QQmlComponent c(&engine, url);
|
||||
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
|
||||
QTest::ignoreMessage(QtWarningMsg, "Only foo can have ItemAttached!");
|
||||
QScopedPointer o(c.create());
|
||||
QVERIFY(o.isNull());
|
||||
QVERIFY(c.errorString().contains(
|
||||
QLatin1String("Could not create attached properties object 'ItemAttached'")));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qqmllanguage)
|
||||
|
||||
#include "tst_qqmllanguage.moc"
|
||||
|
|
Loading…
Reference in New Issue