diff options
author | Luca Beldi <v.ronin@yahoo.it> | 2018-08-22 08:21:01 +0100 |
---|---|---|
committer | Luca Beldi <v.ronin@yahoo.it> | 2018-08-22 08:38:44 +0000 |
commit | 02b3d43fd4661271e6e8dc8940d84cb2ba352fe0 (patch) | |
tree | 814ffd42524fd64f299c7dae0f28e0499653e72b | |
parent | 76c328b2b39617310993ce76e65665943b8c111c (diff) |
_q_interpolate<T> is unsafe with unsigned template arguments
_q_interpolate<T> subtracts 2 arguments of type T,
for unsigned types this can cause wrapping around
Task-number: QTBUG-57925
Change-Id: Iffa59f413579a3d5de8cb728fe71443d8e8a04aa
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-rw-r--r-- | src/corelib/animation/qvariantanimation_p.h | 14 | ||||
-rw-r--r-- | tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp | 25 |
2 files changed, 38 insertions, 1 deletions
diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index 37318a5339..9f0f2e3030 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -58,6 +58,8 @@ #include "private/qabstractanimation_p.h" +#include <type_traits> + #ifndef QT_NO_ANIMATION QT_BEGIN_NAMESPACE @@ -104,7 +106,17 @@ public: }; //this should make the interpolation faster -template<typename T> inline T _q_interpolate(const T &f, const T &t, qreal progress) +template<typename T> +typename std::enable_if<std::is_unsigned<T>::value, T>::type +_q_interpolate(const T &f, const T &t, qreal progress) +{ + return T(f + t * progress - f * progress); +} + +// the below will apply also to all non-arithmetic types +template<typename T> +typename std::enable_if<!std::is_unsigned<T>::value, T>::type +_q_interpolate(const T &f, const T &t, qreal progress) { return T(f + (t - f) * progress); } diff --git a/tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp b/tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp index 00962afa72..ac20fb35ec 100644 --- a/tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp +++ b/tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp @@ -43,6 +43,7 @@ private slots: void keyValueAt(); void keyValues(); void duration(); + void interpolation(); }; class TestableQVariantAnimation : public QVariantAnimation @@ -129,6 +130,30 @@ void tst_QVariantAnimation::duration() QCOMPARE(anim.duration(), 500); } +void tst_QVariantAnimation::interpolation() +{ + QVariantAnimation unsignedAnim; + unsignedAnim.setStartValue(100u); + unsignedAnim.setEndValue(0u); + unsignedAnim.setDuration(100); + unsignedAnim.setCurrentTime(50); + QCOMPARE(unsignedAnim.currentValue().toUInt(), 50u); + + QVariantAnimation signedAnim; + signedAnim.setStartValue(100); + signedAnim.setEndValue(0); + signedAnim.setDuration(100); + signedAnim.setCurrentTime(50); + QCOMPARE(signedAnim.currentValue().toInt(), 50); + + QVariantAnimation pointAnim; + pointAnim.setStartValue(QPoint(100, 100)); + pointAnim.setEndValue(QPoint(0, 0)); + pointAnim.setDuration(100); + pointAnim.setCurrentTime(50); + QCOMPARE(pointAnim.currentValue().toPoint(), QPoint(50, 50)); +} + QTEST_MAIN(tst_QVariantAnimation) #include "tst_qvariantanimation.moc" |