aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-08-02 15:47:58 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-08-04 01:41:34 +0000
commit373d9e438958fed89c482656d947eb77777b6ee0 (patch)
treed7f4c3c805f8d853f997b797e2a5fb8a19a9a739
parent45d5e964bad98793fe3d23bb400de6705a65a67b (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) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-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 7e1c0a3a10..c6e628e02f 100644
--- a/src/qml/qml/qqmlpropertycachecreator.cpp
+++ b/src/qml/qml/qqmlpropertycachecreator.cpp
@@ -129,15 +129,22 @@ void QQmlPendingGroupPropertyBindings::resolveMissingPropertyCaches(
if (propertyCaches->at(groupPropertyObjectIndex))
continue;
- if (pendingBinding.referencingObjectPropertyCache) {
- if (!pendingBinding.resolveInstantiatingProperty())
- continue;
- auto cache = pendingBinding.instantiatingPropertyCache();
- 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();
+ propertyCaches->set(groupPropertyObjectIndex, cache);
}
}
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 038a0cedd3..6d0e5925a8 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -315,12 +315,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 d4a2bf1ad8..59ba9594f9 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -2172,6 +2172,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.