aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLouis du Verdier <louis.du.verdier@free.fr>2018-04-02 20:25:37 +0200
committerLouis du Verdier <louis.du.verdier@free.fr>2018-05-08 16:19:45 +0000
commita609554c031fd57d9a2a3905f5a02cc6b4aa19e9 (patch)
tree22a56bc1cd7a67f447a5a67746376fc5776047e9 /src
parentbdbf6a53c0ab8a7f6ea5586767a6ed818e3d555e (diff)
Fix crash when changing the source of AnimatedImage after a frame change
QMovie emits the signals updated() and frameChanged(), and restarts right after its timer to prepare for the next frame. Since AnimatedImage destroys its underlying QMovie when its source changes, the lines after emit frameChanged() in QMovie will use free'd memory and will most of the time produce a crash. This fix delays the destruction of the underlying QMovie of AnimatedImage using deleteLater() to prevent this kind of behavior from happening without impact/behavior change in the code of QMovie. Unit tests added as well to cover this situation. This commit also fixes a similar crash when Component.onCompleted is called and when the source changes in the associated callback. Task-number: QTBUG-67427 Change-Id: Ic6568a1bc251e5fa2ee1cf8e5f50eaa56c3007db Reviewed-by: VaL Doroshchuk <valentyn.doroshchuk@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Louis du Verdier <louis.du.verdier@free.fr>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickanimatedimage.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index 26dfdb07a6..075c4a7d72 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -426,15 +426,18 @@ void QQuickAnimatedImage::movieRequestFinished()
}
bool pausedAtStart = d->paused;
- if (d->playing)
+ if (d->movie && d->playing)
d->movie->start();
- if (pausedAtStart)
+ if (d->movie && pausedAtStart)
d->movie->setPaused(true);
- if (d->paused || !d->playing) {
+ if (d->movie && (d->paused || !d->playing)) {
d->movie->jumpToFrame(d->presetCurrentFrame);
d->presetCurrentFrame = 0;
}
- d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this)));
+
+ QQuickPixmap *pixmap = d->infoForCurrentFrame(qmlEngine(this));
+ if (pixmap)
+ d->setPixmap(*pixmap);
if (isPlaying() != d->oldPlaying)
emit playingChanged();
@@ -512,7 +515,10 @@ void QQuickAnimatedImagePrivate::setMovie(QMovie *m)
Q_Q(QQuickAnimatedImage);
const int oldFrameCount = q->frameCount();
- delete movie;
+ if (movie) {
+ movie->disconnect();
+ movie->deleteLater();
+ }
movie = m;
if (oldFrameCount != q->frameCount())