aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-08-02 15:47:58 +0200
committerUlf Hermann <ulf.hermann@qt.io>2022-08-04 10:56:20 +0200
commitdc89c0f35aa4c1d2a79814ee5082c605722a679d (patch)
tree6f6f912047755920c4105c29b0470e5920f0b8b6
parent3301b3ed7bbcd52b399b99e838bbb1302c36f778 (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.cpp19
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h6
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.15a.qml12
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp16
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.