diff options
4 files changed, 84 insertions, 1 deletions
diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index cfb6037d14..74930fb373 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -140,6 +140,11 @@ static void qquick_initialize_helper(QAbstractAnimationJob *job, QQuickAnimatorC { if (job->isRenderThreadJob()) { QQuickAnimatorJob *j = static_cast<QQuickAnimatorJob *>(job); + // Note: since a QQuickAnimatorJob::m_target is a QPointer, + // if m_target is destroyed between the time it was set + // as the target of the animator job and before this step, + // (e.g a Loader being set inactive just after starting the animator) + // we are sure it will be NULL and won't be dangling around if (!j->target()) { return; } else if (c->m_deletedSinceLastFrame.contains(j->target())) { diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index 82c9da1d2e..35057d6278 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -152,7 +152,7 @@ protected: QQuickAnimatorJob(); void debugAnimation(QDebug d) const Q_DECL_OVERRIDE; - QQuickItem *m_target; + QPointer<QQuickItem> m_target; QQuickAnimatorController *m_controller; qreal m_from; diff --git a/tests/auto/quick/qquickanimations/data/animatorInvalidTargetCrash.qml b/tests/auto/quick/qquickanimations/data/animatorInvalidTargetCrash.qml new file mode 100644 index 0000000000..f2c378e4b5 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/animatorInvalidTargetCrash.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.3 +import QtQuick.Window 2.2 + +Window { + visible: true + width: 100 + height: 100 + + OpacityAnimator { + id: anim + from: 1 + to:0 + duration: 5000 + running: false + } + + Loader { + id: loader + sourceComponent: Text { + text: "Hello World" + anchors.centerIn: parent + } + } + + Component.onCompleted: { + anim.target = loader.item; + anim.start(); + loader.active = false; + } +} diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index 2b805e9eeb..d234cd2d94 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -104,6 +104,7 @@ private slots: void scriptActionBug(); void groupAnimationNullChildBug(); void scriptActionCrash(); + void animatorInvalidTargetCrash(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -1491,7 +1492,21 @@ void tst_qquickanimations::scriptActionCrash() delete obj; } +// QTBUG-49364 +// Test that we don't crash when the target of an Animator becomes +// invalid between the time the animator is started and the time the +// animator job is actually started +void tst_qquickanimations::animatorInvalidTargetCrash() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("animatorInvalidTargetCrash.qml")); + QObject *obj = c.create(); + //just testing that we don't crash + QTest::qWait(5000); //animator duration + + delete obj; +} QTEST_MAIN(tst_qquickanimations) |