diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2017-09-14 13:47:14 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2017-09-14 11:54:45 +0000 |
commit | e29ffa179e9920443a23e2fcb3f0694df32e8a68 (patch) | |
tree | eb418119709f5f2e72a6331c310471cbc5828135 /src/qml/types/qqmldelegatemodel.cpp | |
parent | 3604cae410f29597c97ba73df6d31a9b54e6d30d (diff) |
Fix use-after-free when removing elements from a ListModel
Detaching delegate instances from model items is done after the
destruction of said model items. The problem is that after the model
item is destroyed, it will emit a change/destroyed signal. As the
delegate is still referencing the item, this will result in a
use-after-free. To provent that, the items are kept around until after
everyone (notably the delegate model) has been notified of the removal.
[ChangeLog][Qt][Qml] Fix possible use-after-free when removing items from a ListModel through JavaScript.
Task-number: QTBUG-59256
Change-Id: Iee182e2cf0b50d3dda2181fed95e38f1a60f22a9
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/types/qqmldelegatemodel.cpp')
-rw-r--r-- | src/qml/types/qqmldelegatemodel.cpp | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 9b1417eccd..26e6a81418 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -1266,6 +1266,13 @@ void QQmlDelegateModel::_q_itemsInserted(int index, int count) d->emitChanges(); } +//### This method should be split in two. It will remove delegates, and it will re-render the list. +// When e.g. QQmlListModel::remove is called, the removal of the delegates should be done on +// QAbstractItemModel::rowsAboutToBeRemoved, and the re-rendering on +// QAbstractItemModel::rowsRemoved. Currently both are done on the latter signal. The problem is +// that the destruction of an item will emit a changed signal that ends up at the delegate, which +// in turn will try to load the data from the model (which should have already freed it), resulting +// in a use-after-free. See QTBUG-59256. void QQmlDelegateModelPrivate::itemsRemoved( const QVector<Compositor::Remove> &removes, QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedRemoves, |