Cocoa: Fix crash in currentModalSession()

Add null-pointer checks to QCocoaEventDispatcher::
currentModalSession():

- window->handle() may return nullptr if the window
has been destroyed.

- We call beginModalSessionForWindow, which processes
events. This can potentially destroy or delete the
current window; pointers to it must be checked again.

This also has the effect that currentModalSessionCached
is not set to a session that does not have a window,
also prevents clearing the cleanupModalSessionsNeeded
flag for such sessions.

Task-number: QTBUG-66536
Change-Id: Ie055933c872a8ede3c938882fb2d4f7cf8ff3c81
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Morten Johan Sørvig 2018-02-20 16:04:56 +01:00
parent dae8133ded
commit eba1d56fad

View File

@ -637,6 +637,8 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
if (!info.session) {
QMacAutoReleasePool pool;
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(info.window->handle());
if (!cocoaWindow)
continue;
NSWindow *nswindow = cocoaWindow->nativeWindow();
if (!nswindow)
continue;
@ -647,6 +649,15 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
[(NSWindow*) info.nswindow retain];
QRect rect = cocoaWindow->geometry();
info.session = [NSApp beginModalSessionForWindow:nswindow];
// The call to beginModalSessionForWindow above processes events and may
// have deleted or destroyed the window. Check if it's still valid.
if (!info.window)
continue;
cocoaWindow = static_cast<QCocoaWindow *>(info.window->handle());
if (!cocoaWindow)
continue;
if (rect != cocoaWindow->geometry())
cocoaWindow->setGeometry(rect);
}