summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2015-05-08 13:49:54 +0200
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2015-05-09 08:41:23 +0000
commit1ac1ae05f551d45772ff2a840dba128abf04171e (patch)
treea71c5963c2bb119f50f90568bd6ed6cbd76ad1c3 /src/widgets/widgets
parent4b7d70886f710767c2b163a08da44d3a7b80479c (diff)
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 <Friedemann.Kleint@theqtcompany.com> Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Diffstat (limited to 'src/widgets/widgets')
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp12
1 files changed, 11 insertions, 1 deletions
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<QAbstractButton *>(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<QDialogButtonBox> guard(q);
+
emit q->clicked(button);
- switch (q->buttonRole(button)) {
+ if (!guard)
+ return;
+
+ switch (buttonRole) {
case QPlatformDialogHelper::AcceptRole:
case QPlatformDialogHelper::YesRole:
emit q->accepted();