aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@qt.io>2024-02-27 08:46:16 +0100
committerPaul Olav Tvete <paul.tvete@qt.io>2024-03-01 22:51:36 +0100
commit6e7fa22d4599484746c91b3e0f5fe2c3332a11e2 (patch)
tree2fc73b43db116bd9b96c2c35d6b233dbedbfe5d4 /src/qml
parentd0823fb78b2e0ab5b31021912806148c47dd29f6 (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')
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp8
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);
}