diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-09-25 08:44:56 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-09-26 17:49:23 +0000 |
commit | 00016ec8048cd32d3d93173fa3197433599bf086 (patch) | |
tree | fa4c9afe638077e653beecda8e1ab33809356a99 | |
parent | 729edeb34e1abd1ef7f738417043e519b2b86a01 (diff) |
QtQml: Check for isReference() before trying to write back
If we neglect this we get an assert further down the line.
Amends commit a824a6f060ec3a0000d7349649a3ab9e0570ecaa.
Change-Id: Ib8fd01d329d5b45b27dfe117e168860c6a1d267f
Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 9c8d76b6ce036fe5e5f17cdcff3c6b22f15b4b65)
(cherry picked from commit c82d1eed1756ddbf0f51953ed9a51dff29d0ef90)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
4 files changed, 13 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index a059ee93b7..1dd2654382 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -511,7 +511,7 @@ int Sequence::virtualMetacall(Object *object, QMetaObject::Call call, int index, switch (call) { case QMetaObject::ReadProperty: { const QMetaType valueType = valueMetaType(sequence->d()); - if (!sequence->loadReference()) + if (sequence->d()->isReference() && !sequence->loadReference()) return 0; const QMetaSequence *metaSequence = sequence->d()->typePrivate()->extraData.ld; if (metaSequence->valueMetaType() != valueType) @@ -529,7 +529,8 @@ int Sequence::virtualMetacall(Object *object, QMetaObject::Call call, int index, if (index < 0 || index >= metaSequence->size(storagePointer)) return 0; metaSequence->setValueAtIndex(storagePointer, index, a[0]); - sequence->storeReference(); + if (sequence->d()->isReference()) + sequence->storeReference(); break; } default: diff --git a/tests/auto/qml/qqmlvaluetypeproviders/data/recursiveWriteBack.qml b/tests/auto/qml/qqmlvaluetypeproviders/data/recursiveWriteBack.qml index d6707e37cd..e2c39d2d72 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/data/recursiveWriteBack.qml +++ b/tests/auto/qml/qqmlvaluetypeproviders/data/recursiveWriteBack.qml @@ -3,11 +3,16 @@ import Test MyTypeObject { property list<structured> l: [{i : 21}, {c: 22}, {p: {x: 199, y: 222}}] + property int aa: 5 Component.onCompleted: { l[2].i = 4 l[1].p.x = 88 l[0].sizes[1].width = 19 structured.p.x = 76 + + var sizesDetached = l[0].sizesDetached(); + sizesDetached[1].width = 12; + aa = sizesDetached[1].width; } } diff --git a/tests/auto/qml/qqmlvaluetypeproviders/testtypes.h b/tests/auto/qml/qqmlvaluetypeproviders/testtypes.h index 096212822d..0267345281 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/testtypes.h +++ b/tests/auto/qml/qqmlvaluetypeproviders/testtypes.h @@ -98,6 +98,8 @@ public: const QList<QSizeF> &sizes() const { return m_sizes; } void setSizes(const QList<QSizeF> &sizes) { m_sizes = sizes; } + Q_INVOKABLE QList<QSizeF> sizesDetached() const { return m_sizes; } + private: friend bool operator==(const StructuredValueType &a, const StructuredValueType &b) diff --git a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp index 5f4d7c1042..930ac11fbe 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp +++ b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp @@ -476,6 +476,9 @@ void tst_qqmlvaluetypeproviders::recursive() MyTypeObject *m = qobject_cast<MyTypeObject *>(o.data()); QCOMPARE(m->structured().p().x(), 76); + + // Recursive write back into a list detached from the property. + QCOMPARE(m->property("aa").toInt(), 12); } void tst_qqmlvaluetypeproviders::date() |