[epiphany/gnome-3-22] web-view: Fix memory leaks when web view is closed before info bar



commit b2c1bd64a38ade3f805b9245fef63f48340a6c7b
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Sat Jan 14 15:18:21 2017 -0600

    web-view: Fix memory leaks when web view is closed before info bar
    
    The current info bar management code improperly assumes that the user
    will always close the info bar before closing its associated web view.
    If the user closes the web view first, then we leak the FormAuthData
    or PermissionRequestData struct in EphyWebView. In the case of
    PermissionRequestData, that notably contains an unresolved
    WebKitPermissionRequest. Additionally, for form auth data requests, the
    hash table entry for the outstanding request in the web extension is
    leaked because the web extension never receives the expected form auth
    data request response.
    
    Resolve this by tracking the destruction of the info bars with a weak
    reference.

 embed/ephy-web-view.c |   27 +++++++++++++++++++++++++--
 1 files changed, 25 insertions(+), 2 deletions(-)
---
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index b1c1ddc..7eeed2a 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -691,18 +691,30 @@ form_auth_request_data_free (FormAuthRequestData *data)
 }
 
 static void
+form_auth_save_confirmation_info_bar_destroyed_cb (FormAuthRequestData *data,
+                                                   GObject             *where_the_info_bar_was)
+{
+  /* Ensure the hash table entry in the web process is removed. */
+  if (data->web_view->web_extension)
+    ephy_web_extension_proxy_form_auth_data_save_confirmation_response (data->web_view->web_extension,
+                                                                        data->request_id,
+                                                                        FALSE);
+  form_auth_request_data_free (data);
+}
+
+static void
 form_auth_data_save_confirmation_response (GtkInfoBar          *info_bar,
                                            gint                 response_id,
                                            FormAuthRequestData *data)
 {
-  gtk_widget_destroy (GTK_WIDGET (info_bar));
-
   if (data->web_view->web_extension) {
     ephy_web_extension_proxy_form_auth_data_save_confirmation_response (data->web_view->web_extension,
                                                                         data->request_id,
                                                                         response_id == GTK_RESPONSE_YES);
   }
 
+  g_object_weak_unref (G_OBJECT (info_bar), (GWeakNotify)form_auth_save_confirmation_info_bar_destroyed_cb, 
data);
+  gtk_widget_destroy (GTK_WIDGET (info_bar));
   form_auth_request_data_free (data);
 }
 
@@ -732,6 +744,7 @@ form_auth_data_save_requested (EphyEmbedShell *shell,
   g_signal_connect (info_bar, "response",
                     G_CALLBACK (form_auth_data_save_confirmation_response),
                     data);
+  g_object_weak_ref (G_OBJECT (info_bar), (GWeakNotify)form_auth_save_confirmation_info_bar_destroyed_cb, 
data);
 
   gtk_widget_show (info_bar);
 }
@@ -1279,6 +1292,14 @@ permission_request_data_free (PermissionRequestData *data)
 }
 
 static void
+permission_request_info_bar_destroyed_cb (PermissionRequestData *data,
+                                          GObject               *where_the_info_bar_was)
+{
+  webkit_permission_request_deny (data->request);
+  permission_request_data_free (data);
+}
+
+static void
 decide_on_permission_request (GtkWidget               *info_bar,
                               int                      response,
                               PermissionRequestData   *data)
@@ -1303,6 +1324,7 @@ decide_on_permission_request (GtkWidget               *info_bar,
     }
   }
 
+  g_object_weak_unref (G_OBJECT (info_bar), (GWeakNotify)permission_request_info_bar_destroyed_cb, data);
   gtk_widget_destroy (info_bar);
   permission_request_data_free (data);
 }
@@ -1385,6 +1407,7 @@ permission_request_cb (WebKitWebView           *web_view,
   g_signal_connect (info_bar, "response",
                     G_CALLBACK (decide_on_permission_request),
                     data);
+  g_object_weak_ref (G_OBJECT (info_bar), (GWeakNotify)permission_request_info_bar_destroyed_cb, data);
   g_free (host);
 
   if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST (decision))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]