Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
6.5.5, 6.6.2, 6.7.0 Beta3
-
None
-
-
8afac5e5f (dev), 57e9ac23b (6.8), eeadcc68b (6.7), e4da1520f (tqtc/lts-6.5)
Description
QQuickItemViewPrivate::releaseItem() is called with during clear(), setCurrentIndex(), updatePolish(), setModel() and others. In releaseItem the current item is finally deleted but before it's quick item is possibly reparented:
item->item->setParentItem(nullptr);
This reparenting action itself may trigger further signals and these signals could again cause QQuickItemViewPrivate::releaseItem() to be called recursively.
This causes a crash because the currentItem pointer is nulled after releaseItem() is called:
releaseItem(currentItem, QQmlDelegateModel::NotReusable); currentItem = nullptr;
Here is the scenario:
releaseItem() is called with currentItem:
bool QQuickItemViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag)
{
......
item->item->setParentItem(nullptr);
......
delete item;
return ...;
}
Here, setParentItem causes recursive call releaseItem() with currentItem which is finally deleted. After returning from setParentItem the pointer item is dangling. Thus, its final deletion causes a crash.
I suggest nulling currentItem pointer before calling releaseItem():
auto oldCurrentItem = currentItem; currentItem = nullptr; releaseItem(oldCurrentItem, QQmlDelegateModel::NotReusable);
Attachments
For Gerrit Dashboard: QTBUG-122998 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
569487,3 | Item/PathView: reset the currentItem before releasing it | dev | qt/qtdeclarative | Status: MERGED | +2 | 0 |
569711,2 | Item/PathView: reset the currentItem before releasing it | 6.8 | qt/qtdeclarative | Status: MERGED | +2 | 0 |
569825,2 | Item/PathView: reset the currentItem before releasing it | 6.7 | qt/qtdeclarative | Status: MERGED | +2 | 0 |
569993,2 | Item/PathView: reset the currentItem before releasing it | tqtc/lts-6.5 | qt/tqtc-qtdeclarative | Status: MERGED | +2 | 0 |