From 0b129f3534381e8ef659c57d470aeb17fe87b252 Mon Sep 17 00:00:00 2001 From: Andrew Chadwick Date: Fri, 18 Nov 2016 15:12:57 +0000 Subject: [PATCH] win32 event: check for NULL display or dev mgr The recent Wintab testing revealed an interesting edge case: we cannot for certain say that windowing system messages will not be received while the default display and its device manager are still being set up. We've ruled out the Wintab case now, but cannot rule out some future bit of runtime DLL code doing stuff at this critical time. This commit detects and avoids a potential null pointer dereference in the message handling code while detecting grabs. Grabs don't really exist yet, if the default display and/or its device manager are not yet globally known. https://bugzilla.gnome.org/show_bug.cgi?id=774379 --- gdk/win32/gdkevents-win32.c | 39 ++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index cc103a18e0..7c77f0a472 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -2097,10 +2097,10 @@ gdk_event_translate (MSG *msg, GdkWindow *window = NULL; GdkWindowImplWin32 *impl; - GdkWindow *new_window; + GdkWindow *new_window = NULL; - GdkDeviceManager *device_manager; - GdkDeviceManagerWin32 *device_manager_win32; + GdkDeviceManager *device_manager = NULL; + GdkDeviceManagerWin32 *device_manager_win32 = NULL; GdkDeviceGrabInfo *keyboard_grab = NULL; GdkDeviceGrabInfo *pointer_grab = NULL; @@ -2153,13 +2153,34 @@ gdk_event_translate (MSG *msg, return FALSE; } - device_manager = gdk_display_get_device_manager (display); - device_manager_win32 = GDK_DEVICE_MANAGER_WIN32 (device_manager); + /* gdk_event_translate() can be called during initialization, if something + * sends MSGs. In this case, the default display or its device manager will + * be NULL, so avoid trying to read the active grabs. + * https://bugzilla.gnome.org/show_bug.cgi?id=774379 + */ + if (display != NULL) + { + device_manager = gdk_display_get_device_manager (display); + } + else + { + GDK_NOTE (EVENTS, g_print (" (no GdkDisplay)")); + } - keyboard_grab = _gdk_display_get_last_device_grab (display, - device_manager_win32->core_keyboard); - pointer_grab = _gdk_display_get_last_device_grab (display, - device_manager_win32->core_pointer); + if (device_manager != NULL) + { + device_manager_win32 = GDK_DEVICE_MANAGER_WIN32 (device_manager); + } + else + { + GDK_NOTE (EVENTS, g_print (" (no GdkDeviceManager)")); + } + + if (device_manager_win32 != NULL) + { + keyboard_grab = _gdk_display_get_last_device_grab (display, device_manager_win32->core_keyboard); + pointer_grab = _gdk_display_get_last_device_grab (display, device_manager_win32->core_pointer); + } g_object_ref (window);