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:
Ulf Hermann 2022-04-27 11:22:05 +02:00
parent 01f6ba9949
commit 25eca6b7cf
4 changed files with 66 additions and 0 deletions

View File

@ -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);

View File

@ -0,0 +1,8 @@
import QtQml
import ABC
QtObject {
id: testItem
objectName: "00000000000000000000"
ItemAttached.attachedName: "111111111"
}

View File

@ -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

View File

@ -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"