diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-08-02 15:47:58 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-08-04 01:41:34 +0000 |
commit | 373d9e438958fed89c482656d947eb77777b6ee0 (patch) | |
tree | d7f4c3c805f8d853f997b797e2a5fb8a19a9a739 | |
parent | 45d5e964bad98793fe3d23bb400de6705a65a67b (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.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 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. |