diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-08-02 15:47:58 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-08-04 10:56:20 +0200 |
commit | dc89c0f35aa4c1d2a79814ee5082c605722a679d (patch) | |
tree | 6f6f912047755920c4105c29b0470e5920f0b8b6 | |
parent | 3301b3ed7bbcd52b399b99e838bbb1302c36f778 (diff) |
Qml: Don't crash on nested group properties with aliases
This fixes an oversight where in case of half-resolved grouped
properties we would forget to add the bindings to the "pending" list.
In addition we would fail to resolve their property caches later on.
Fixes: QTBUG-94983
Change-Id: I88bd0ce56464438d2a105e5ed426e002495cc016
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit fed5b07980d9ae5a392a00563f70ee34fc261dbc)
-rw-r--r-- | src/qml/qml/qqmlpropertycachecreator.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycachecreator_p.h | 6 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/data/alias.15a.qml | 12 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 16 |
4 files changed, 42 insertions, 11 deletions
diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp index 45edb59cfb..5e5a3aa840 100644 --- a/src/qml/qml/qqmlpropertycachecreator.cpp +++ b/src/qml/qml/qqmlpropertycachecreator.cpp @@ -149,15 +149,22 @@ void QQmlPendingGroupPropertyBindings::resolveMissingPropertyCaches(QQmlEnginePr if (propertyCaches->at(groupPropertyObjectIndex)) continue; - if (pendingBinding.referencingObjectPropertyCache) { - if (!pendingBinding.resolveInstantiatingProperty()) - continue; - auto cache = pendingBinding.instantiatingPropertyCache(enginePrivate); - propertyCaches->set(groupPropertyObjectIndex, cache); - } else { + if (pendingBinding.instantiatingPropertyName.isEmpty()) { + // Generalized group property. auto cache = propertyCaches->at(pendingBinding.referencingObjectIndex); propertyCaches->set(groupPropertyObjectIndex, cache); + continue; + } + + if (!pendingBinding.referencingObjectPropertyCache) { + pendingBinding.referencingObjectPropertyCache + = propertyCaches->at(pendingBinding.referencingObjectIndex); } + + if (!pendingBinding.resolveInstantiatingProperty()) + continue; + auto cache = pendingBinding.instantiatingPropertyCache(enginePrivate); + propertyCaches->set(groupPropertyObjectIndex, cache); } } diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 606628cbe8..c8d516b367 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -348,12 +348,8 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecur switch (binding->type()) { case QV4::CompiledData::Binding::Type_Object: case QV4::CompiledData::Binding::Type_GroupProperty: - // We can resolve object and group properties if we have a property cache. - if (thisCache) - break; - continue; case QV4::CompiledData::Binding::Type_AttachedProperty: - // We can always resolve attached properties. + // We can always resolve object, group, and attached properties. break; default: // Everything else is of no interest here. diff --git a/tests/auto/qml/qqmllanguage/data/alias.15a.qml b/tests/auto/qml/qqmllanguage/data/alias.15a.qml new file mode 100644 index 0000000000..ba8097c997 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/alias.15a.qml @@ -0,0 +1,12 @@ +import QtQuick 2.15 + +Item { + id: root + + property alias symbol: symbol + symbol.layer.enabled: true + + Item { + id: symbol + } +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index ab9062d8a1..4a7a0b4085 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -2173,6 +2173,22 @@ void tst_qqmllanguage::aliasProperties() QCOMPARE(subItem->property("y").toInt(), 1); } + // Nested property bindings on group properties that are actually aliases (QTBUG-94983) + { + QQmlComponent component(&engine, testFileUrl("alias.15a.qml")); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QPointer<QObject> subItem = qvariant_cast<QObject*>(object->property("symbol")); + QVERIFY(!subItem.isNull()); + + QPointer<QObject> subSubItem = qvariant_cast<QObject*>(subItem->property("layer")); + + QCOMPARE(subSubItem->property("enabled").value<bool>(), true); + } + // Alias to sub-object with binding (QTBUG-57041) { // This is shold *not* crash. |