diff options
author | Jan Arve Sæther <jan-arve.saether@qt.io> | 2023-10-25 17:00:47 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-11-02 10:10:09 +0000 |
commit | a2de295be30a471cf904c7f68f9acbbf71a6fd83 (patch) | |
tree | e2bfcdc7e6e0e8edd83fce71e405fcd622243215 | |
parent | f3d04fdcde181a047d2a6c753e0304d026f0ca9b (diff) |
Fix crash when calling QQmlIncubator::abort()
QQuickContainerPrivate::itemDestroyed did not properly
clean up its internal data structures to have no references to the item
that got destroyed. This was mainly because the call to
q->isContent(item)
in QQuickContainerPrivate::removeItem() would return false, so it would
not continue doing the rest of the required cleanup that removeItem
does, and it was therefore leaving dangling pointers to the destroyed
item in QQuickContainers data structures.
Pick-to: 6.5
Fixes: QTBUG-118397
Change-Id: I7f23b4f98df33d69b42455d20016adb7e132b510
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit 47b4037ccca3d9d38c2d172bafdeb5dcce699eb7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/quicktemplates/qquickcontainer.cpp | 10 | ||||
-rw-r--r-- | tests/auto/quickcontrols/deferred/data/abortedIncubation.qml | 10 |
2 files changed, 17 insertions, 3 deletions
diff --git a/src/quicktemplates/qquickcontainer.cpp b/src/quicktemplates/qquickcontainer.cpp index 8c35fcb633..b696b1812c 100644 --- a/src/quicktemplates/qquickcontainer.cpp +++ b/src/quicktemplates/qquickcontainer.cpp @@ -256,7 +256,8 @@ void QQuickContainerPrivate::moveItem(int from, int to, QQuickItem *item) void QQuickContainerPrivate::removeItem(int index, QQuickItem *item) { Q_Q(QQuickContainer); - if (!q->isContent(item)) + const bool item_inDestructor = QQuickItemPrivate::get(item)->inDestructor; + if (!item_inDestructor && !q->isContent(item)) return; contentData.removeOne(item); @@ -271,8 +272,11 @@ void QQuickContainerPrivate::removeItem(int index, QQuickItem *item) currentChanged = true; } - QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes); - item->setParentItem(nullptr); + if (!item_inDestructor) { + // already handled by ~QQuickItem + QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes); + item->setParentItem(nullptr); + } contentModel->remove(index); --count; diff --git a/tests/auto/quickcontrols/deferred/data/abortedIncubation.qml b/tests/auto/quickcontrols/deferred/data/abortedIncubation.qml index 519a779402..6cd4c1c04a 100644 --- a/tests/auto/quickcontrols/deferred/data/abortedIncubation.qml +++ b/tests/auto/quickcontrols/deferred/data/abortedIncubation.qml @@ -157,5 +157,15 @@ ApplicationWindow { color: "pink" } } + + TabBar { + id: bar + TabButton { + text: qsTr("One") + } + TabButton { + text: qsTr("Two") + } + } } |