summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/accessible
diff options
context:
space:
mode:
authorJan Arve Saether <jan-arve.saether@digia.com>2012-12-07 15:29:06 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-12-11 18:34:19 +0100
commitced154500de1dde42033579a7b29494934d8a02d (patch)
tree97fa07da70f8714a2f26860e2843ae8a090d7c8e /src/plugins/platforms/windows/accessible
parent03e1e4138ccf6b73c73b2fed6db0e740af43ef76 (diff)
a11y: Do not refer to destructed QObject in Windows bridge
The crash could happen if a QWidget in the UI got deleted, and the AT client later tried to access the widget through the cache (qAccessibleRecentSentEvents()). Solution: Use a QPointer as a guard. Task-number: QTBUG-26187 Change-Id: I1aa716766626cf171757e76ba255a6d5ae4fd854 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
Diffstat (limited to 'src/plugins/platforms/windows/accessible')
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp30
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp2
2 files changed, 22 insertions, 10 deletions
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
index db2d5f949f..b94fef56ba 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
@@ -48,6 +48,7 @@
#include <QtCore/qlocale.h>
#include <QtCore/qmap.h>
#include <QtCore/qpair.h>
+#include <QtCore/qpointer.h>
#include <QtCore/qsettings.h>
#include <QtGui/qaccessible.h>
#include <QtGui/qaccessible2.h>
@@ -87,10 +88,9 @@
// This stuff is used for widgets/items with no window handle:
-typedef QMap<int, QPair<QObject*,int> > NotifyMap;
+typedef QMap<int, QPair<QPointer<QObject>,int> > NotifyMap;
Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents)
-
QT_BEGIN_NAMESPACE
@@ -193,14 +193,25 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", window);
static int eventNum = 0;
- if (event->type() != QAccessible::MenuCommand) { // MenuCommand is faked
- // See comment "SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE"
+ if (event->type() != QAccessible::MenuCommand && // MenuCommand is faked
+ event->type() != QAccessible::ObjectDestroyed) {
+ /* In some rare occasions, the server (Qt) might get a ::get_accChild call with a
+ childId that references an entry in the cache where there was a dangling
+ QObject-pointer. Previously we crashed on this.
+
+ There is no point in actually notifying the AT client that the object got destroyed,
+ because the AT client won't query for get_accChild if the event is ObjectDestroyed
+ anyway, and we have no other way of mapping the eventId argument to the actual
+ child/descendant object. (Firefox seems to simply completely ignore
+ EVENT_OBJECT_DESTROY).
+
+ We therefore guard each QObject in the cache with a QPointer, and only notify the AT
+ client if the type is not ObjectDestroyed.
+ */
eventNum %= 50; //[0..49]
int eventId = - (eventNum - 1);
-
- qAccessibleRecentSentEvents()->insert(eventId, qMakePair(event->object(), event->child()));
- ptrNotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, eventId );
-
+ qAccessibleRecentSentEvents()->insert(eventId, qMakePair(QPointer<QObject>(event->object()), event->child()));
+ ptrNotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, eventId);
++eventNum;
}
#endif // Q_OS_WINCE
@@ -244,7 +255,8 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc)
*/
QPair<QObject*, int> QWindowsAccessibility::getCachedObject(int entryId)
{
- return qAccessibleRecentSentEvents()->value(entryId);
+ QPair<QPointer<QObject>, int> pair = qAccessibleRecentSentEvents()->value(entryId);
+ return qMakePair(pair.first.data(), pair.second);
}
/*
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 328053604e..f1bdc77303 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -757,7 +757,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChild(VARIANT varChildI
acc = res;
}
} else {
- qWarning("get_accChild got a negative varChildID, but did not find it in cache");
+ qWarning("get_accChild got a negative varChildID (%d), but did not find it in cache", childIndex);
}
} else {
if (childIndex) {