From 1ac1ae05f551d45772ff2a840dba128abf04171e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 8 May 2015 13:49:54 +0200 Subject: QDialogButtonBox: prevent crashes on deletions in slots As usual, user code connected to signals emitted from Qt may destroy an object's internal status while a signal is being emitted. Guard a bit QDialogButtonBox signal emissions to prevent crashes in case the button or a dialog get deleted from a slot connected to clicked(). Also, be sure to emit the corresponding accepted/rejected/etc. signal. Change-Id: I7b1888070a8f2f56aa60923a17f90fb5efef145c Task-number: QTBUG-45835 Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Marc Mutz --- src/widgets/widgets/qdialogbuttonbox.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/widgets/widgets') diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 237eb775b9..3e8c08f923 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -852,9 +852,19 @@ void QDialogButtonBoxPrivate::_q_handleButtonClicked() { Q_Q(QDialogButtonBox); if (QAbstractButton *button = qobject_cast(q->sender())) { + // Can't fetch this *after* emitting clicked, as clicked may destroy the button + // or change its role. Now changing the role is not possible yet, but arguably + // both clicked and accepted/rejected/etc. should be emitted "atomically" + // depending on whatever role the button had at the time of the click. + const QDialogButtonBox::ButtonRole buttonRole = q->buttonRole(button); + QPointer guard(q); + emit q->clicked(button); - switch (q->buttonRole(button)) { + if (!guard) + return; + + switch (buttonRole) { case QPlatformDialogHelper::AcceptRole: case QPlatformDialogHelper::YesRole: emit q->accepted(); -- cgit v1.2.3