From ec543f79c7d036961eb6cdcd956b3e8ca28b8e54 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 6 Nov 2009 08:49:00 +1000 Subject: Fix possible crash when overriding a signal handler. --- src/declarative/qml/qmlboundsignal.cpp | 2 +- src/declarative/util/qmlpropertychanges.cpp | 4 ++-- .../declarative/states/data/signalOverrideCrash.qml | 15 +++++++++++++++ tests/auto/declarative/states/tst_states.cpp | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/states/data/signalOverrideCrash.qml diff --git a/src/declarative/qml/qmlboundsignal.cpp b/src/declarative/qml/qmlboundsignal.cpp index def11c3..deb15dc 100644 --- a/src/declarative/qml/qmlboundsignal.cpp +++ b/src/declarative/qml/qmlboundsignal.cpp @@ -177,7 +177,7 @@ int QmlBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a) if (m_params) m_params->setValues(a); if (m_expression) { QmlExpressionPrivate::get(m_expression)->value(m_params); - if (m_expression->hasError()) + if (m_expression && m_expression->hasError()) qWarning().nospace() << qPrintable(m_expression->error().toString()); } if (m_params) m_params->clearValues(); diff --git a/src/declarative/util/qmlpropertychanges.cpp b/src/declarative/util/qmlpropertychanges.cpp index 3cc6ca9..3aa3678 100644 --- a/src/declarative/util/qmlpropertychanges.cpp +++ b/src/declarative/util/qmlpropertychanges.cpp @@ -232,7 +232,7 @@ void QmlPropertyChangesPrivate::decode() ds >> data; QmlMetaProperty prop = property(name); //### better way to check for signal property? - if (prop.type() == QmlMetaProperty::SignalProperty) { + if (prop.type() & QmlMetaProperty::SignalProperty) { QmlExpression *expression = new QmlExpression(qmlContext(q), data.toString(), object); expression->setTrackChange(false); QmlReplaceSignalHandler *handler = new QmlReplaceSignalHandler; @@ -307,7 +307,7 @@ QmlPropertyChangesPrivate::property(const QByteArray &property) if (!prop.isValid()) { qmlInfo(QmlPropertyChanges::tr("Cannot assign to non-existant property \"%1\"").arg(QString::fromUtf8(property)), q); return QmlMetaProperty(); - } else if (prop.type() != QmlMetaProperty::SignalProperty && !prop.isWritable()) { + } else if (!(prop.type() & QmlMetaProperty::SignalProperty) && !prop.isWritable()) { qmlInfo(QmlPropertyChanges::tr("Cannot assign to read-only property \"%1\"").arg(QString::fromUtf8(property)), q); return QmlMetaProperty(); } diff --git a/tests/auto/declarative/states/data/signalOverrideCrash.qml b/tests/auto/declarative/states/data/signalOverrideCrash.qml new file mode 100644 index 0000000..702fa86 --- /dev/null +++ b/tests/auto/declarative/states/data/signalOverrideCrash.qml @@ -0,0 +1,15 @@ +import Qt 4.6 +import Qt.test 1.0 + +MyRectangle { + id: rect + + width: 100; height: 100 + states: State { + name: "overridden" + PropertyChanges { + target: rect + onDidSomething: rect.state = "" + } + } +} diff --git a/tests/auto/declarative/states/tst_states.cpp b/tests/auto/declarative/states/tst_states.cpp index f67c737..d6df37e 100644 --- a/tests/auto/declarative/states/tst_states.cpp +++ b/tests/auto/declarative/states/tst_states.cpp @@ -54,6 +54,7 @@ private slots: void basicExtension(); void basicBinding(); void signalOverride(); + void signalOverrideCrash(); void parentChange(); void anchorChanges(); void script(); @@ -356,6 +357,23 @@ void tst_states::signalOverride() } } +void tst_states::signalOverrideCrash() +{ + QmlEngine engine; + + QmlComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash.qml"); + MyRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + //QCOMPARE(rect->color(),QColor("red")); + //rect->doSomething(); + //QCOMPARE(rect->color(),QColor("blue")); + + rect->setState("overridden"); + rect->doSomething(); + //QCOMPARE(rect->color(),QColor("green")); +} + void tst_states::parentChange() { QmlEngine engine; -- cgit v0.12