Fix crash when assigning a list property to transitions.
authorMichael Brasser <michael.brasser@nokia.com>
Mon, 25 Jul 2011 06:43:55 +0000 (16:43 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 26 Jul 2011 07:37:52 +0000 (09:37 +0200)
This fixes the crash, but doesn't actually assign any
Transitions (the transitions list will now be empty, rather
than contain a null Transition object). Correct assignment
is a general language issue, and will be fixed separately.

Task-number: QTBUG-20227
Change-Id: Ie224d06b1d8bb82d03c5eba378affb7167f08724
Reviewed-by: Alan Alpert
Reviewed-on: http://codereview.qt.nokia.com/2152
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
src/declarative/util/qdeclarativestategroup.cpp
src/qtquick1/util/qdeclarativestategroup.cpp
tests/auto/declarative/qdeclarativeanimations/data/transitionAssignmentBug.qml [new file with mode: 0644]
tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
tests/auto/qtquick1/qdeclarativeanimations/data/transitionAssignmentBug.qml [new file with mode: 0644]
tests/auto/qtquick1/qdeclarativeanimations/tst_qdeclarativeanimations.cpp

index a3f57d4..c098a38 100644 (file)
@@ -73,6 +73,11 @@ public:
     static QDeclarativeState *at_state(QDeclarativeListProperty<QDeclarativeState> *list, int index);
     static void clear_states(QDeclarativeListProperty<QDeclarativeState> *list);
 
+    static void append_transition(QDeclarativeListProperty<QDeclarativeTransition> *list, QDeclarativeTransition *state);
+    static int count_transitions(QDeclarativeListProperty<QDeclarativeTransition> *list);
+    static QDeclarativeTransition *at_transition(QDeclarativeListProperty<QDeclarativeTransition> *list, int index);
+    static void clear_transitions(QDeclarativeListProperty<QDeclarativeTransition> *list);
+
     QList<QDeclarativeState *> states;
     QList<QDeclarativeTransition *> transitions;
 
@@ -218,7 +223,35 @@ void QDeclarativeStateGroupPrivate::clear_states(QDeclarativeListProperty<QDecla
 QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeStateGroup::transitionsProperty()
 {
     Q_D(QDeclarativeStateGroup);
-    return QDeclarativeListProperty<QDeclarativeTransition>(this, d->transitions);
+    return QDeclarativeListProperty<QDeclarativeTransition>(this, &d->transitions, &QDeclarativeStateGroupPrivate::append_transition,
+                                                       &QDeclarativeStateGroupPrivate::count_transitions,
+                                                       &QDeclarativeStateGroupPrivate::at_transition,
+                                                       &QDeclarativeStateGroupPrivate::clear_transitions);
+}
+
+void QDeclarativeStateGroupPrivate::append_transition(QDeclarativeListProperty<QDeclarativeTransition> *list, QDeclarativeTransition *trans)
+{
+    QDeclarativeStateGroup *_this = static_cast<QDeclarativeStateGroup *>(list->object);
+    if (trans)
+        _this->d_func()->transitions.append(trans);
+}
+
+int QDeclarativeStateGroupPrivate::count_transitions(QDeclarativeListProperty<QDeclarativeTransition> *list)
+{
+    QDeclarativeStateGroup *_this = static_cast<QDeclarativeStateGroup *>(list->object);
+    return _this->d_func()->transitions.count();
+}
+
+QDeclarativeTransition *QDeclarativeStateGroupPrivate::at_transition(QDeclarativeListProperty<QDeclarativeTransition> *list, int index)
+{
+    QDeclarativeStateGroup *_this = static_cast<QDeclarativeStateGroup *>(list->object);
+    return _this->d_func()->transitions.at(index);
+}
+
+void QDeclarativeStateGroupPrivate::clear_transitions(QDeclarativeListProperty<QDeclarativeTransition> *list)
+{
+    QDeclarativeStateGroup *_this = static_cast<QDeclarativeStateGroup *>(list->object);
+    _this->d_func()->transitions.clear();
 }
 
 /*!
index 6bf1a2f..60ca08c 100644 (file)
@@ -75,6 +75,11 @@ public:
     static QDeclarative1State *at_state(QDeclarativeListProperty<QDeclarative1State> *list, int index);
     static void clear_states(QDeclarativeListProperty<QDeclarative1State> *list);
 
+    static void append_transition(QDeclarativeListProperty<QDeclarative1Transition> *list, QDeclarative1Transition *state);
+    static int count_transitions(QDeclarativeListProperty<QDeclarative1Transition> *list);
+    static QDeclarative1Transition *at_transition(QDeclarativeListProperty<QDeclarative1Transition> *list, int index);
+    static void clear_transitions(QDeclarativeListProperty<QDeclarative1Transition> *list);
+
     QList<QDeclarative1State *> states;
     QList<QDeclarative1Transition *> transitions;
 
@@ -221,7 +226,35 @@ void QDeclarative1StateGroupPrivate::clear_states(QDeclarativeListProperty<QDecl
 QDeclarativeListProperty<QDeclarative1Transition> QDeclarative1StateGroup::transitionsProperty()
 {
     Q_D(QDeclarative1StateGroup);
-    return QDeclarativeListProperty<QDeclarative1Transition>(this, d->transitions);
+    return QDeclarativeListProperty<QDeclarative1Transition>(this, &d->transitions, &QDeclarative1StateGroupPrivate::append_transition,
+                                                       &QDeclarative1StateGroupPrivate::count_transitions,
+                                                       &QDeclarative1StateGroupPrivate::at_transition,
+                                                       &QDeclarative1StateGroupPrivate::clear_transitions);
+}
+
+void QDeclarative1StateGroupPrivate::append_transition(QDeclarativeListProperty<QDeclarative1Transition> *list, QDeclarative1Transition *trans)
+{
+    QDeclarative1StateGroup *_this = static_cast<QDeclarative1StateGroup *>(list->object);
+    if (trans)
+        _this->d_func()->transitions.append(trans);
+}
+
+int QDeclarative1StateGroupPrivate::count_transitions(QDeclarativeListProperty<QDeclarative1Transition> *list)
+{
+    QDeclarative1StateGroup *_this = static_cast<QDeclarative1StateGroup *>(list->object);
+    return _this->d_func()->transitions.count();
+}
+
+QDeclarative1Transition *QDeclarative1StateGroupPrivate::at_transition(QDeclarativeListProperty<QDeclarative1Transition> *list, int index)
+{
+    QDeclarative1StateGroup *_this = static_cast<QDeclarative1StateGroup *>(list->object);
+    return _this->d_func()->transitions.at(index);
+}
+
+void QDeclarative1StateGroupPrivate::clear_transitions(QDeclarativeListProperty<QDeclarative1Transition> *list)
+{
+    QDeclarative1StateGroup *_this = static_cast<QDeclarative1StateGroup *>(list->object);
+    _this->d_func()->transitions.clear();
 }
 
 /*!
diff --git a/tests/auto/declarative/qdeclarativeanimations/data/transitionAssignmentBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/transitionAssignmentBug.qml
new file mode 100644 (file)
index 0000000..508693e
--- /dev/null
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+Rectangle {
+    width: 400
+    height: 400
+
+    property bool nullObject
+    Component.onCompleted: nullObject = transitions.length > 0 && transitions[0] === null
+
+    property list<Transition> myTransitions: [Transition {}, Transition {}]
+    transitions: myTransitions
+}
index cf911c6..9308aca 100644 (file)
@@ -88,6 +88,7 @@ private slots:
     void registrationBug();
     void doubleRegistrationBug();
     void alwaysRunToEndRestartBug();
+    void transitionAssignmentBug();
 };
 
 #define QTIMED_COMPARE(lhs, rhs) do { \
@@ -844,6 +845,18 @@ void tst_qdeclarativeanimations::alwaysRunToEndRestartBug()
     QCOMPARE(static_cast<QDeclarativeAbstractAnimation*>(&animation)->qtAnimation()->state(), QAbstractAnimation::Stopped);
 }
 
+//QTBUG-20227
+void tst_qdeclarativeanimations::transitionAssignmentBug()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent c(&engine, SRCDIR "/data/transitionAssignmentBug.qml");
+    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QVERIFY(rect != 0);
+
+    QCOMPARE(rect->property("nullObject").toBool(), false);
+}
+
 QTEST_MAIN(tst_qdeclarativeanimations)
 
 #include "tst_qdeclarativeanimations.moc"
diff --git a/tests/auto/qtquick1/qdeclarativeanimations/data/transitionAssignmentBug.qml b/tests/auto/qtquick1/qdeclarativeanimations/data/transitionAssignmentBug.qml
new file mode 100644 (file)
index 0000000..99b9ac5
--- /dev/null
@@ -0,0 +1,12 @@
+import QtQuick 1.0
+
+Rectangle {
+    width: 400
+    height: 400
+
+    property bool nullObject
+    Component.onCompleted: nullObject = transitions.length > 0 && transitions[0] === null
+
+    property list<Transition> myTransitions: [Transition {}, Transition {}]
+    transitions: myTransitions
+}
index 6f75ce3..228f4fd 100644 (file)
@@ -88,6 +88,7 @@ private slots:
     void registrationBug();
     void doubleRegistrationBug();
     void alwaysRunToEndRestartBug();
+    void transitionAssignmentBug();
 };
 
 #define QTIMED_COMPARE(lhs, rhs) do { \
@@ -850,6 +851,18 @@ void tst_qdeclarativeanimations::alwaysRunToEndRestartBug()
     QCOMPARE(static_cast<QDeclarative1AbstractAnimation*>(&animation)->qtAnimation()->state(), QAbstractAnimation::Stopped);
 }
 
+//QTBUG-20227
+void tst_qdeclarativeanimations::transitionAssignmentBug()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent c(&engine, SRCDIR "/data/transitionAssignmentBug.qml");
+    QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
+    QVERIFY(rect != 0);
+
+    QCOMPARE(rect->property("nullObject").toBool(), false);
+}
+
 QTEST_MAIN(tst_qdeclarativeanimations)
 
 #include "tst_qdeclarativeanimations.moc"