diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-06-05 15:54:24 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-06-08 19:26:40 +0200 |
commit | a8ef2c12635db3fcd46e600d3a49baa7bcaa6225 (patch) | |
tree | 5354af2cb45caa4909ecfacbe3e87a77162a15f5 /src/qml/qml/qqmlcontextdata.cpp | |
parent | 84a687cc784bde49855073e4016172e0321ba13b (diff) |
Prevent premature child destruction
QQmlContextData::emitDestruction suffers from the fact that code can
delete objects while emitDestruction is ongoing. Notably, the sequence
child->emitDestruction can trigger a call to a->destruction (of one of
child's attached components), which then can indirectly delete both
child and child->nextChild (for instance, when a StackView gets
cleared).
We prevent this by using QQmlRefPointer when iterating over the
children, which keeps the child alive for the duration of the loop.
This solves the same issue as 0c8e51705ac0bb86c4b123ecd30a11b41fd50b24
in 5.15
Fixes: QTBUG-84095
Change-Id: I486a65f791c2a52d6c5c0f188997225b6db75267
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlcontextdata.cpp')
-rw-r--r-- | src/qml/qml/qqmlcontextdata.cpp | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/qml/qml/qqmlcontextdata.cpp b/src/qml/qml/qqmlcontextdata.cpp index 33be23b14d..d9aea9b917 100644 --- a/src/qml/qml/qqmlcontextdata.cpp +++ b/src/qml/qml/qqmlcontextdata.cpp @@ -87,7 +87,7 @@ void QQmlContextData::emitDestruction() emit attached->destruction(); } - for (QQmlContextData *child = m_childContexts; child; child = child->m_nextChild) + for (QQmlRefPointer<QQmlContextData> child = m_childContexts; !child.isNull(); child = child->m_nextChild) child->emitDestruction(); } } @@ -144,12 +144,12 @@ void QQmlContextData::clearContext() QQmlContextData::~QQmlContextData() { Q_ASSERT(refCount() == 0); - m_linkedContext = nullptr; // avoid recursion addref(); if (m_engine) invalidate(); + m_linkedContext = nullptr; Q_ASSERT(refCount() == 1); clearContext(); |