[GTK] UIProcess crashes when using Japanese IM
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 10 Oct 2016 07:12:35 +0000 (07:12 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 10 Oct 2016 07:12:35 +0000 (07:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163011

We have to reference the current GdkEventKey before we try process it
as later when the lambda body is reached the event could be already
freed.

Patch by Tomas Popela <tpopela@redhat.com> on 2016-10-10
Reviewed by Carlos Garcia Campos.

* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseKeyPressEvent):
(webkitWebViewBaseKeyReleaseEvent):
* UIProcess/gtk/InputMethodFilter.h:
Use non-copyable Function so we can use WTFMove to pass the event to
lambda.

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

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
Source/WebKit2/UIProcess/gtk/InputMethodFilter.h

index 97b0b10..ee3195b 100644 (file)
@@ -1,3 +1,21 @@
+2016-10-10  Tomas Popela  <tpopela@redhat.com>
+
+        [GTK] UIProcess crashes when using Japanese IM
+        https://bugs.webkit.org/show_bug.cgi?id=163011
+
+        We have to reference the current GdkEventKey before we try process it
+        as later when the lambda body is reached the event could be already
+        freed.
+
+        Reviewed by Carlos Garcia Campos.
+
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseKeyPressEvent):
+        (webkitWebViewBaseKeyReleaseEvent):
+        * UIProcess/gtk/InputMethodFilter.h:
+        Use non-copyable Function so we can use WTFMove to pass the event to
+        lambda.
+
 2016-10-09  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Support InputEvent.inputType for the new InputEvent spec
index 5a80559..6740216 100644 (file)
@@ -674,17 +674,17 @@ static gboolean webkitWebViewBaseFocusOutEvent(GtkWidget* widget, GdkEventFocus*
     return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus_out_event(widget, event);
 }
 
-static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* event)
+static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* keyEvent)
 {
     WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
 
     if (priv->authenticationDialog)
-        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, event);
+        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, keyEvent);
 
 #if ENABLE(FULLSCREEN_API)
     if (priv->fullScreenModeActive) {
-        switch (event->keyval) {
+        switch (keyEvent->keyval) {
         case GDK_KEY_Escape:
         case GDK_KEY_f:
         case GDK_KEY_F:
@@ -702,29 +702,33 @@ static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* e
     // using gtk_main_do_event().
     if (priv->shouldForwardNextKeyEvent) {
         priv->shouldForwardNextKeyEvent = FALSE;
-        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, event);
+        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, keyEvent);
     }
 
-    priv->inputMethodFilter.filterKeyEvent(event, [priv, event](const WebCore::CompositionResults& compositionResults, InputMethodFilter::EventFakedForComposition faked) {
-        priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(event), compositionResults, faked,
-            !compositionResults.compositionUpdated() ? priv->keyBindingTranslator.commandsForKeyEvent(event) : Vector<String>()));
+    // We need to copy the event as otherwise it could be destroyed before we reach the lambda body.
+    GUniquePtr<GdkEvent> event(gdk_event_copy(reinterpret_cast<GdkEvent*>(keyEvent)));
+    priv->inputMethodFilter.filterKeyEvent(keyEvent, [priv, event = WTFMove(event)](const WebCore::CompositionResults& compositionResults, InputMethodFilter::EventFakedForComposition faked) {
+        priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(event.get(), compositionResults, faked,
+            !compositionResults.compositionUpdated() ? priv->keyBindingTranslator.commandsForKeyEvent(&event->key) : Vector<String>()));
     });
 
     return TRUE;
 }
 
-static gboolean webkitWebViewBaseKeyReleaseEvent(GtkWidget* widget, GdkEventKey* event)
+static gboolean webkitWebViewBaseKeyReleaseEvent(GtkWidget* widget, GdkEventKey* keyEvent)
 {
     WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
 
     if (priv->shouldForwardNextKeyEvent) {
         priv->shouldForwardNextKeyEvent = FALSE;
-        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_release_event(widget, event);
+        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_release_event(widget, keyEvent);
     }
 
-    priv->inputMethodFilter.filterKeyEvent(event, [priv, event](const WebCore::CompositionResults& compositionResults, InputMethodFilter::EventFakedForComposition faked) {
-        priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(event), compositionResults, faked, { }));
+    // We need to copy the event as otherwise it could be destroyed before we reach the lambda body.
+    GUniquePtr<GdkEvent> event(gdk_event_copy(reinterpret_cast<GdkEvent*>(keyEvent)));
+    priv->inputMethodFilter.filterKeyEvent(keyEvent, [priv, event = WTFMove(event)](const WebCore::CompositionResults& compositionResults, InputMethodFilter::EventFakedForComposition faked) {
+        priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(event.get(), compositionResults, faked, { }));
     });
 
     return TRUE;
index 6d2cee6..f6d66eb 100644 (file)
@@ -21,7 +21,7 @@
 #define InputMethodFilter_h
 
 #include <WebCore/IntPoint.h>
-#include <functional>
+#include <wtf/Function.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/glib/GRefPtr.h>
 #include <wtf/text/WTFString.h>
@@ -56,7 +56,7 @@ public:
     void setEnabled(bool);
     void setCursorRect(const WebCore::IntRect&);
 
-    using FilterKeyEventCompletionHandler = std::function<void (const WebCore::CompositionResults&, InputMethodFilter::EventFakedForComposition)>;
+    using FilterKeyEventCompletionHandler = Function<void(const WebCore::CompositionResults&, InputMethodFilter::EventFakedForComposition)>;
     void filterKeyEvent(GdkEventKey*, FilterKeyEventCompletionHandler&& = nullptr);
     void notifyFocusedIn();
     void notifyFocusedOut();