diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2024-02-27 08:46:16 +0100 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2024-03-01 22:51:36 +0100 |
commit | 6e7fa22d4599484746c91b3e0f5fe2c3332a11e2 (patch) | |
tree | 2fc73b43db116bd9b96c2c35d6b233dbedbfe5d4 /src/qml/animations | |
parent | d0823fb78b2e0ab5b31021912806148c47dd29f6 (diff) |
Fix crash on exit when pause animation is running
At program exit, QThreadStorage will delete the QQmlAnimationTimer. In
the destructor, any currently active animation job will be unregistered.
The animation timer has a list of all top-level animations, and a list
of running pause animations. A pause animation that is a child of a
group (the normal case) would not be removed from the list when its
parent was removed. This caused a read-after-free when the animation
timer tried to update the deleted pause animation.
To fix this, make sure that pause animations are removed from the list
also when the parent is unregistered.
Fixes: QTBUG-120433
Pick-to: 6.7 6.6 6.5
Change-Id: Ic6b5a8f09593114c50daf5525824cc814abb79f9
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/qml/animations')
-rw-r--r-- | src/qml/animations/qabstractanimationjob.cpp | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp index 7bb2af476c..a50685ba50 100644 --- a/src/qml/animations/qabstractanimationjob.cpp +++ b/src/qml/animations/qabstractanimationjob.cpp @@ -37,6 +37,9 @@ void QQmlAnimationTimer::unsetJobTimer(QAbstractAnimationJob *animation) if (animation->m_timer == this) animation->m_timer = nullptr; + if (animation->m_isPause) + runningPauseAnimations.removeOne(animation); + if (animation->isGroup()) { QAnimationGroupJob *group = static_cast<QAnimationGroupJob *>(animation); if (const auto children = group->children()) { @@ -214,10 +217,9 @@ void QQmlAnimationTimer::unregisterRunningAnimation(QAbstractAnimationJob *anima if (animation->m_isGroup) return; - if (animation->m_isPause) - runningPauseAnimations.removeOne(animation); - else + if (!animation->m_isPause) runningLeafAnimations--; + Q_ASSERT(runningLeafAnimations >= 0); } |