[GTK][Wayland] Crash when gdk_keymap_get_entries_for_keyval returns TRUE but n_keys=0
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Aug 2017 14:07:11 +0000 (14:07 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Aug 2017 14:07:11 +0000 (14:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=176154

Reviewed by Carlos Alberto Lopez Perez.

Source/WebKit:

In Wayland gdk_keymap_get_entries_for_keyval() can return TRUE with n_keys=0. We have several places in WebKit
where we just check the return value of gdk_keymap_get_entries_for_keyval() and then use the returned array to
get the first position assuming it has at least one item. This has always worked in X11 because the GDK X11
backend does the right thing, but it's crashing in Wayland now. It should be fixed in GTK+ but in the meantime
it's easy to workaround by also checking n_keys > 0.

* UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp:
(WebKit::doKeyStrokeEvent):

Tools:

Also check the n_keys > 0 when using gdk_keymap_get_entries_for_keyval().

* TestWebKitAPI/Tests/WebKit/gtk/InputMethodFilter.cpp:
(TestWebKitAPI::TestInputMethodFilter::sendKeyEventToFilter):
* TestWebKitAPI/Tests/WebKitGtk/TestPrinting.cpp: Remove duplicated code and use WebViewTest::keyStroke instead.
* TestWebKitAPI/glib/WebKitGLib/gtk/WebViewTestGtk.cpp:
(WebViewTest::keyStroke):
* TestWebKitAPI/gtk/PlatformWebViewGtk.cpp:
(TestWebKitAPI::doKeyStroke):
* WebKitTestRunner/gtk/EventSenderProxyGtk.cpp:
(WTR::EventSenderProxy::keyDown):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221419 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKit/gtk/InputMethodFilter.cpp
Tools/TestWebKitAPI/Tests/WebKitGtk/TestPrinting.cpp
Tools/TestWebKitAPI/glib/WebKitGLib/gtk/WebViewTestGtk.cpp
Tools/TestWebKitAPI/gtk/PlatformWebViewGtk.cpp
Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp

index a3572b5..01346e5 100644 (file)
@@ -1,3 +1,19 @@
+2017-08-31  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK][Wayland] Crash when gdk_keymap_get_entries_for_keyval returns TRUE but n_keys=0
+        https://bugs.webkit.org/show_bug.cgi?id=176154
+
+        Reviewed by Carlos Alberto Lopez Perez.
+
+        In Wayland gdk_keymap_get_entries_for_keyval() can return TRUE with n_keys=0. We have several places in WebKit
+        where we just check the return value of gdk_keymap_get_entries_for_keyval() and then use the returned array to
+        get the first position assuming it has at least one item. This has always worked in X11 because the GDK X11
+        backend does the right thing, but it's crashing in Wayland now. It should be fixed in GTK+ but in the meantime
+        it's easy to workaround by also checking n_keys > 0.
+
+        * UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp:
+        (WebKit::doKeyStrokeEvent):
+
 2017-08-30  Dan Bernstein  <mitz@apple.com>
 
         [iOS] REGRESSION (r218144) -[WKContentView targetForAction:withSender:] returns the content view for actions implemented only by the WKWebView, causing a crash
index 0d4214a..c06771c 100644 (file)
@@ -145,7 +145,7 @@ static void doKeyStrokeEvent(GdkEventType type, GtkWidget* widget, unsigned keyV
     // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+.
     GUniqueOutPtr<GdkKeymapKey> keys;
     int keysCount;
-    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount))
+    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount) && keysCount)
         event->key.hardware_keycode = keys.get()[0].keycode;
 
     gtk_main_do_event(event.get());
index 3329f22..030adb2 100644 (file)
@@ -1,5 +1,24 @@
 2017-08-31  Carlos Garcia Campos  <cgarcia@igalia.com>
 
+        [GTK][Wayland] Crash when gdk_keymap_get_entries_for_keyval returns TRUE but n_keys=0
+        https://bugs.webkit.org/show_bug.cgi?id=176154
+
+        Reviewed by Carlos Alberto Lopez Perez.
+
+        Also check the n_keys > 0 when using gdk_keymap_get_entries_for_keyval().
+
+        * TestWebKitAPI/Tests/WebKit/gtk/InputMethodFilter.cpp:
+        (TestWebKitAPI::TestInputMethodFilter::sendKeyEventToFilter):
+        * TestWebKitAPI/Tests/WebKitGtk/TestPrinting.cpp: Remove duplicated code and use WebViewTest::keyStroke instead.
+        * TestWebKitAPI/glib/WebKitGLib/gtk/WebViewTestGtk.cpp:
+        (WebViewTest::keyStroke):
+        * TestWebKitAPI/gtk/PlatformWebViewGtk.cpp:
+        (TestWebKitAPI::doKeyStroke):
+        * WebKitTestRunner/gtk/EventSenderProxyGtk.cpp:
+        (WTR::EventSenderProxy::keyDown):
+
+2017-08-31  Carlos Garcia Campos  <cgarcia@igalia.com>
+
         Unreviewed. Fix GTK+ test /webkit2/WebKitAutomationSession/request-session.
 
         It fails when comparing the browser version if micro version is 0 (or if both micro and minor are 0 too).
index 4a0e684..2de790f 100644 (file)
@@ -67,7 +67,7 @@ public:
 
         GUniqueOutPtr<GdkKeymapKey> keys;
         gint nKeys;
-        if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeyValue, &keys.outPtr(), &nKeys))
+        if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeyValue, &keys.outPtr(), &nKeys) && nKeys)
             event->key.hardware_keycode = keys.get()[0].keycode;
 
         filterKeyEvent(&event->key);
index 2b52211..710ae9c 100644 (file)
@@ -365,32 +365,6 @@ public:
         g_main_loop_quit(m_mainLoop);
     }
 
-    void sendKeyEvent(unsigned gdkKeyValue, GdkEventType type, unsigned modifiers)
-    {
-        GdkEvent* event = gdk_event_new(type);
-        event->key.keyval = gdkKeyValue;
-        event->key.state = modifiers;
-        event->key.window = gtk_widget_get_window(GTK_WIDGET(m_webView));
-        event->key.time = GDK_CURRENT_TIME;
-        g_object_ref(event->key.window);
-        gdk_event_set_device(event, gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_display_get_default())));
-
-        GUniqueOutPtr<GdkKeymapKey> keys;
-        gint nKeys;
-        if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeyValue, &keys.outPtr(), &nKeys))
-            event->key.hardware_keycode = keys.get()[0].keycode;
-
-        gtk_main_do_event(event);
-
-        gdk_event_free(event);
-    }
-
-    void sendKeyPressAndReleaseEvent(unsigned gdkKeyValue, unsigned modifiers = 0)
-    {
-        sendKeyEvent(gdkKeyValue, GDK_KEY_PRESS, modifiers);
-        sendKeyEvent(gdkKeyValue, GDK_KEY_RELEASE, modifiers);
-    }
-
     void createWebKitPrintOperation()
     {
         m_printOperation = adoptGRef(webkit_print_operation_new(m_webView));
@@ -410,23 +384,23 @@ public:
     void startPrinting()
     {
         // To start printing it is enough to press the Return key
-        sendKeyPressAndReleaseEvent(GDK_KEY_Return);
+        keyStroke(GDK_KEY_Return);
     }
 
     void jumpToFirstPrinter()
     {
         // Initially the GtkNotebook has focus, so we just need to press the Tab
         // key to jump to the first printer
-        sendKeyPressAndReleaseEvent(GDK_KEY_Tab);
+        keyStroke(GDK_KEY_Tab);
     }
 
     void jumpToCustomWidget()
     {
         // Jump back to the GtkNotebook
-        sendKeyPressAndReleaseEvent(GDK_KEY_Tab, GDK_SHIFT_MASK);
+        keyStroke(GDK_KEY_Tab, GDK_SHIFT_MASK);
         // Custom widget is on the third tab
-        sendKeyPressAndReleaseEvent(GDK_KEY_Right);
-        sendKeyPressAndReleaseEvent(GDK_KEY_Right);
+        keyStroke(GDK_KEY_Right);
+        keyStroke(GDK_KEY_Right);
     }
 
     void openDialogMoveThroughItAndWaitUntilClosed()
index 8b3d8ba..a1341a6 100644 (file)
@@ -148,7 +148,7 @@ void WebViewTest::keyStroke(unsigned keyVal, unsigned keyModifiers)
     // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+.
     GUniqueOutPtr<GdkKeymapKey> keys;
     int keysCount;
-    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount))
+    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount) && keysCount)
         event->key.hardware_keycode = keys.get()[0].keycode;
 
     gtk_main_do_event(event.get());
index 0feb2b5..17c226b 100644 (file)
@@ -95,7 +95,7 @@ static void doKeyStroke(GtkWidget* viewWidget, unsigned int keyVal)
     // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+.
     GUniqueOutPtr<GdkKeymapKey> keys;
     int keysCount;
-    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount))
+    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount) && keysCount)
         event->key.hardware_keycode = keys.get()[0].keycode;
 
     gtk_main_do_event(event.get());
index 8508b71..378141d 100644 (file)
@@ -315,7 +315,7 @@ void EventSenderProxy::keyDown(WKStringRef keyRef, WKEventModifiers wkModifiers,
 
     GUniqueOutPtr<GdkKeymapKey> keys;
     gint nKeys;
-    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeySym, &keys.outPtr(), &nKeys))
+    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeySym, &keys.outPtr(), &nKeys) && nKeys)
         pressEvent->key.hardware_keycode = keys.get()[0].keycode;
 
     GdkEvent* releaseEvent = gdk_event_copy(pressEvent);