File kstyle-no-dynamic-cast-bnc529640.diff of Package kdelibs4
------------------------------------------------------------------------
r1034808 | lunakl | 2009-10-13 15:34:28 +0000 (Tue, 13 Oct 2009) | 7 lines
Changed paths:
M /trunk/KDE/kdelibs/kdeui/kernel/kstyle.h
Plugins really shouldn't use dynamic_cast, it breaks without RTLD_GLOBAL
and especially with plugins that is quite likely to happen with 3rd party
apps (e.g. http://bugzilla.novell.com/529640).
And the best I could come up with was playing with typeid().name(), which
works, except for subclassing.
------------------------------------------------------------------------
Index: kdeui/kernel/kstyle.h
===================================================================
--- kdeui/kernel/kstyle.h (revision 1034807)
+++ kdeui/kernel/kstyle.h (revision 1034808)
@@ -40,6 +40,7 @@
#include <QtGui/QCommonStyle>
#include <QtGui/QPalette>
#include <QtGui/QStylePlugin>
+#include <typeinfo>
class QStyleOptionProgressBar;
class QStyleOptionTab;
@@ -1578,6 +1579,9 @@
// fitt's law label support: QLabel focusing its buddy widget
const QObject *clickedLabel;
+ template<typename T>
+ static T extractOptionHelper(T*);
+
public:
/** @name QStyle Methods
* These are methods reimplemented from QStyle. Usually it's not necessary to
@@ -1669,12 +1673,25 @@
}
};
+// get the pointed-to type from a pointer
+template<typename T>
+T KStyle::extractOptionHelper(T*)
+{
+ return T();
+}
template<typename T>
T KStyle::extractOption(Option* option)
{
- if (option && dynamic_cast<T>(option)) {
- return static_cast<T>(option);
+ if (option) {
+ if (dynamic_cast<T>(option))
+ return static_cast<T>(option);
+ // Ugly hacks for when RTLD_GLOBAL is not used (quite common with plugins, really)
+ // and dynamic_cast fails.
+ // This is still partially broken as it doesn't take into account subclasses.
+ // ### KDE5 do this somehow differently
+ if ( qstrcmp(typeid(*option).name(), typeid(extractOptionHelper(static_cast<T>(0))).name()) == 0 )
+ return static_cast<T>(option);
}
//### warn if cast failed?