Commit b63ce68f authored by Charles Yin's avatar Charles Yin Committed by Qt by Nokia

Fix crash issue for path animation and path interpulator

When set progress value out of [0,1], path animation and
path interpulator should make sure the value be modified
in the valid value range, otherwise the QQuickPath::backwardsPointAt()
will crash.

Task-number: QTBUG-24308
Change-Id: Icd6e9165c9f844ddb8ec84c229eac4db5246a749
Reviewed-by: 's avatarMichael Brasser <michael.brasser@nokia.com>
parent c913351c
...@@ -927,6 +927,8 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio ...@@ -927,6 +927,8 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio
void QQuickPathAnimationUpdater::setValue(qreal v) void QQuickPathAnimationUpdater::setValue(qreal v)
{ {
v = qMin(qMax(v, (qreal)0.0), (qreal)1.0);;
if (interruptStart.isValid()) { if (interruptStart.isValid()) {
if (reverse) if (reverse)
v = 1 - v; v = 1 - v;
......
...@@ -527,6 +527,8 @@ QPointF QQuickPath::sequentialPointAt(qreal p, qreal *angle) const ...@@ -527,6 +527,8 @@ QPointF QQuickPath::sequentialPointAt(qreal p, qreal *angle) const
QPointF QQuickPath::sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle) QPointF QQuickPath::sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle)
{ {
Q_ASSERT(p >= 0.0 && p <= 1.0);
if (!prevBez.isValid) if (!prevBez.isValid)
return p > .5 ? backwardsPointAt(path, pathLength, attributePoints, prevBez, p, angle) : return p > .5 ? backwardsPointAt(path, pathLength, attributePoints, prevBez, p, angle) :
forwardsPointAt(path, pathLength, attributePoints, prevBez, p, angle); forwardsPointAt(path, pathLength, attributePoints, prevBez, p, angle);
......
...@@ -102,6 +102,8 @@ qreal QQuickPathInterpolator::progress() const ...@@ -102,6 +102,8 @@ qreal QQuickPathInterpolator::progress() const
void QQuickPathInterpolator::setProgress(qreal progress) void QQuickPathInterpolator::setProgress(qreal progress)
{ {
progress = qMin(qMax(progress, (qreal)0.0), (qreal)1.0);
if (progress == _progress) if (progress == _progress)
return; return;
_progress = progress; _progress = progress;
......
import QtQuick 2.0
Item {
id: root
width: 450; height: 600
Rectangle {
objectName:"rect"
id: rect
x:200
y:500
width: 225; height: 40
color: "lightsteelblue"
}
PathAnimation {
id:anim
running:true
duration: 200
easing.type: Easing.InOutBack
target:rect
path: Path {
PathLine { x: 0; y: 0 }
}
}
}
\ No newline at end of file
...@@ -107,6 +107,7 @@ private slots: ...@@ -107,6 +107,7 @@ private slots:
void pauseBug(); void pauseBug();
void loopingBug(); void loopingBug();
void anchorBug(); void anchorBug();
void pathAnimationInOutBackBug();
}; };
#define QTIMED_COMPARE(lhs, rhs) do { \ #define QTIMED_COMPARE(lhs, rhs) do { \
...@@ -455,6 +456,13 @@ void tst_qquickanimations::pathInterpolator() ...@@ -455,6 +456,13 @@ void tst_qquickanimations::pathInterpolator()
QCOMPARE(interpolator->x(), qreal(300)); QCOMPARE(interpolator->x(), qreal(300));
QCOMPARE(interpolator->y(), qreal(300)); QCOMPARE(interpolator->y(), qreal(300));
QCOMPARE(interpolator->angle(), qreal(0)); QCOMPARE(interpolator->angle(), qreal(0));
//for path interpulator the progress value must be [0,1] range.
interpolator->setProgress(1.1);
QCOMPARE(interpolator->progress(), qreal(1));
interpolator->setProgress(-0.000123);
QCOMPARE(interpolator->progress(), qreal(0));
} }
void tst_qquickanimations::pathInterpolatorBackwardJump() void tst_qquickanimations::pathInterpolatorBackwardJump()
...@@ -1171,6 +1179,22 @@ void tst_qquickanimations::runningTrueBug() ...@@ -1171,6 +1179,22 @@ void tst_qquickanimations::runningTrueBug()
QVERIFY(cloud->x() > qreal(0)); QVERIFY(cloud->x() > qreal(0));
} }
//QTBUG-24308
void tst_qquickanimations::pathAnimationInOutBackBug()
{
//ensure we don't pass bad progress value (out of [0,1]) to QQuickPath::backwardsPointAt()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathAnimationInOutBackCrash.qml"));
QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
QVERIFY(item);
QQuickRectangle *rect = item->findChild<QQuickRectangle *>("rect");
QVERIFY(rect);
QTest::qWait(1000);
QCOMPARE(rect->x(), qreal(0));
QCOMPARE(rect->y(), qreal(0));
}
//QTBUG-12805 //QTBUG-12805
void tst_qquickanimations::nonTransitionBug() void tst_qquickanimations::nonTransitionBug()
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment