summaryrefslogtreecommitdiffstats
path: root/src/widgets/dialogs/qdialog_p.h
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-07-11 19:55:24 +0200
committerMarc Mutz <marc.mutz@kdab.com>2017-02-06 14:41:46 +0000
commitc876bb1f1333e47722e202b0916415e771137071 (patch)
tree34401974dd6a2993561b577b07b20955a696adb7 /src/widgets/dialogs/qdialog_p.h
parentbbd091ac5853d7884929369da4e1b5d233ca504c (diff)
QInputDialog: prevent crash in static get*() functions when parent gets deleted
As explained in https://blogs.kde.org/2009/03/26/how-crash-almost-every-qtkde-application-and-how-fix-it-0 creating dialogs on the stack is a bad idea if the application or the dialog's parent window can be closed by means other than user interaction (such as a timer or an IPC call). Since we cannot know whether Qt is used to build such an application, we must assume it is, create the dialog on the heap, and monitor its lifetime with a QPointer. Instead of using manual resource management, add a minimal implementation of QAutoPointer, and use that in all static get*() functions. Task-number: QTBUG-54693 Change-Id: I6157dca18608e02be1ea2c2defbc31641defc9d1 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: David Faure <david.faure@kdab.com>
Diffstat (limited to 'src/widgets/dialogs/qdialog_p.h')
-rw-r--r--src/widgets/dialogs/qdialog_p.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h
index 1c7c5f3c2a..ae9e3bcc93 100644
--- a/src/widgets/dialogs/qdialog_p.h
+++ b/src/widgets/dialogs/qdialog_p.h
@@ -119,6 +119,24 @@ private:
mutable bool m_platformHelperCreated;
};
+template <typename T>
+class QAutoPointer {
+ QPointer<T> o;
+ struct internal { void func() {} };
+ typedef void (internal::*RestrictedBool)();
+public:
+ explicit QAutoPointer(T *t) Q_DECL_NOTHROW : o(t) {}
+ ~QAutoPointer() { delete o; }
+
+ T *operator->() const Q_DECL_NOTHROW { return get(); }
+ T *get() const Q_DECL_NOTHROW { return o; }
+ T &operator*() const { return *get(); }
+ operator RestrictedBool() const Q_DECL_NOTHROW { return o ? &internal::func : Q_NULLPTR; }
+ bool operator!() const Q_DECL_NOTHROW { return !o; }
+private:
+ Q_DISABLE_COPY(QAutoPointer);
+};
+
QT_END_NAMESPACE
#endif // QDIALOG_P_H