diff options
author | Ulf Hermann <[email protected]> | 2025-06-23 13:44:40 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2025-06-29 19:46:38 +0200 |
commit | aa1d3e416edd092f3dc8f8a20f15bd92baa93485 (patch) | |
tree | 39fb196527573301002ef7cfc196136b2fbea840 | |
parent | b0d9b0ff37ad9d08ec75257ca76ee964803f5659 (diff) |
Value type proxy bindings don't set the binding bit in the first place.
Therefore, we'd never find one this way. When different bindings set
properties of the same value type property in different places, this
would crash.
Pick-to: 6.10 6.9 6.8 6.5
Fixes: QTBUG-137326
Change-Id: Ie5ddb840f3f056ce5c9e04689511986e0eb28123
Reviewed-by: Fabian Kosmale <[email protected]>
-rw-r--r-- | src/qml/qml/qqmlabstractbinding.cpp | 15 | ||||
-rw-r--r-- | tests/auto/qml/qqmlbinding/data/multiValueTypeBinding.qml | 16 | ||||
-rw-r--r-- | tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp | 18 |
3 files changed, 41 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp index 78d1d68f55..d1c0a855d1 100644 --- a/src/qml/qml/qqmlabstractbinding.cpp +++ b/src/qml/qml/qqmlabstractbinding.cpp @@ -49,16 +49,15 @@ void QQmlAbstractBinding::addToObject() // Find the value type proxy (if there is one) QQmlValueTypeProxyBinding *proxy = nullptr; - if (data->hasBindingBit(coreIndex)) { - QQmlAbstractBinding *b = data->bindings; - while (b && (b->targetPropertyIndex().coreIndex() != coreIndex || - b->targetPropertyIndex().hasValueTypeIndex())) - b = b->nextBinding(); - Q_ASSERT(b && b->kind() == QQmlAbstractBinding::ValueTypeProxy); - proxy = static_cast<QQmlValueTypeProxyBinding *>(b); + QQmlAbstractBinding *b = data->bindings; + while (b && (b->targetPropertyIndex().coreIndex() != coreIndex || + b->targetPropertyIndex().hasValueTypeIndex())) { + b = b->nextBinding(); } - if (!proxy) { + if (b && b->kind() == QQmlAbstractBinding::ValueTypeProxy) { + proxy = static_cast<QQmlValueTypeProxyBinding *>(b); + } else { proxy = new QQmlValueTypeProxyBinding(obj, QQmlPropertyIndex(coreIndex)); Q_ASSERT(proxy->targetPropertyIndex().coreIndex() == coreIndex); diff --git a/tests/auto/qml/qqmlbinding/data/multiValueTypeBinding.qml b/tests/auto/qml/qqmlbinding/data/multiValueTypeBinding.qml new file mode 100644 index 0000000000..7f1ba9b886 --- /dev/null +++ b/tests/auto/qml/qqmlbinding/data/multiValueTypeBinding.qml @@ -0,0 +1,16 @@ +import QtQml + +QtObject { + property alias labelY: label.rect.y + property alias labelWidth: label.rect.width + + labelY: { return 24 } + labelWidth: 9 + + property QtObject label: QtObject { + id: label + + property rect rect + rect.x: { return 12 } + } +} diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp index e4c1013cb9..11905c8210 100644 --- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp +++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp @@ -55,6 +55,7 @@ private slots: void qQmlPropertyToPropertyBindingReverse(); void delayedBindingDestruction(); void deleteStashedObject(); + void multiValueTypeBinding(); private: QQmlEngine engine; @@ -910,6 +911,23 @@ void tst_qqmlbinding::deleteStashedObject() QTRY_VERIFY(object->property("page").value<QObject *>() == nullptr); } +void tst_qqmlbinding::multiValueTypeBinding() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("multiValueTypeBinding.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> object(component.create()); + QVERIFY(object); + + QObject *label = object->property("label").value<QObject *>(); + QVERIFY(label); + + QRectF rect = label->property("rect").toRectF(); + QCOMPARE(rect.x(), 12); + QCOMPARE(rect.y(), 24); + QCOMPARE(rect.width(), 9); +} + QTEST_MAIN(tst_qqmlbinding) #include "tst_qqmlbinding.moc" |