From d54b11fef6403693de09277a645c9666f8eea6a2 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 17 Mar 2010 19:07:38 +1000 Subject: Fix crash If the notifier gets swapped out during emitting, the endpoint is also invalidated. Thus the "disconnected" writeback must track the endpoint not just the Notifier. --- src/declarative/qml/qdeclarativeexpression.cpp | 1 + src/declarative/qml/qdeclarativenotifier.cpp | 14 +++++++------- src/declarative/qml/qdeclarativenotifier_p.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 20863c7..9eed345 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -98,6 +98,7 @@ QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() if (data) { delete [] data->guardList; data->guardList = 0; + data->guardListLength = 0; data->q = 0; data->release(); data = 0; diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp index 8e5904c..b12bf77 100644 --- a/src/declarative/qml/qdeclarativenotifier.cpp +++ b/src/declarative/qml/qdeclarativenotifier.cpp @@ -47,23 +47,23 @@ void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint) { QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier(); - QDeclarativeNotifierEndpoint::Notifier **oldDisconnected = n->disconnected; - n->disconnected = &n; + QDeclarativeNotifierEndpoint **oldDisconnected = n->disconnected; + n->disconnected = &endpoint; if (n->next) emitNotify(n->next); - if (n) { + if (endpoint) { void *args[] = { 0 }; QMetaObject::metacall(endpoint->target, QMetaObject::InvokeMetaMethod, endpoint->targetMethod, args); - if (n) - n->disconnected = oldDisconnected; + if (endpoint) + endpoint->asNotifier()->disconnected = oldDisconnected; } - if (oldDisconnected) *oldDisconnected = n; + if (oldDisconnected) *oldDisconnected = endpoint; } void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &other) @@ -89,7 +89,7 @@ void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &ot other_n->notifier = n->notifier; other_n->disconnected = n->disconnected; - if (other_n->disconnected) *other_n->disconnected = other_n; + if (other_n->disconnected) *other_n->disconnected = &other; if (n->next) { other_n->next = n->next; diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h index 2a8087e..2a9660d 100644 --- a/src/declarative/qml/qdeclarativenotifier_p.h +++ b/src/declarative/qml/qdeclarativenotifier_p.h @@ -91,7 +91,7 @@ private: struct Notifier { QDeclarativeNotifier *notifier; - Notifier **disconnected; + QDeclarativeNotifierEndpoint **disconnected; QDeclarativeNotifierEndpoint *next; QDeclarativeNotifierEndpoint **prev; -- cgit v0.12