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);