telepathy-haze: request: fix resource leakage

Will Thompson wjt at kemper.freedesktop.org
Thu Apr 11 11:42:47 PDT 2013


Module: telepathy-haze
Branch: master
Commit: eef971c3aeb61b9b60013f3b728f62e7ac5580bf
URL:    http://cgit.freedesktop.org/telepathy/telepathy-haze/commit/?id=eef971c3aeb61b9b60013f3b728f62e7ac5580bf

Author: Stefan Becker <chemobejk at gmail.com>
Date:   Wed Apr 10 16:13:04 2013 +0300

request: fix resource leakage

It is the responsibility of the UI code to free the "fields" parameter
after haze_request_fields() has been called. This has to be done with
purple_request_close() and handled in the close_request() UI operation.

https://bugs.freedesktop.org/show_bug.cgi?id=63326

---

 src/request.c |   65 ++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 41 insertions(+), 24 deletions(-)

diff --git a/src/request.c b/src/request.c
index dae859d..db54317 100644
--- a/src/request.c
+++ b/src/request.c
@@ -101,7 +101,7 @@ haze_request_action (const char *title,
 }
 #endif
 
-struct password_data {
+struct fields_data {
     PurpleRequestFields *fields;
     PurpleRequestField *password;
     GCallback ok_cb;
@@ -109,21 +109,40 @@ struct password_data {
     void *user_data;
 };
 
+static void haze_close_request(PurpleRequestType type, void *ui_handle)
+{
+    struct fields_data *fd = ui_handle;
+
+    purple_request_fields_destroy(fd->fields);
+    g_free(fd);
+}
+
 void haze_request_password_cb (gpointer user_data,
                                const gchar *password)
 {
-    struct password_data *pd = user_data;
+    struct fields_data *fd = user_data;
 
     if (password) {
-        purple_request_field_string_set_value(pd->password, password);
-        ((PurpleRequestFieldsCb)pd->ok_cb)(pd->user_data, pd->fields);
+        purple_request_field_string_set_value(fd->password, password);
+        ((PurpleRequestFieldsCb)fd->ok_cb)(fd->user_data, fd->fields);
     } else {
-        ((PurpleRequestFieldsCb)pd->cancel_cb)(pd->user_data, pd->fields);
+        ((PurpleRequestFieldsCb)fd->cancel_cb)(fd->user_data, fd->fields);
     }
 
-    g_free(pd);
+    purple_request_close(PURPLE_REQUEST_FIELDS, fd);
 }
 
+static gboolean haze_request_fields_destroy(gpointer user_data)
+{
+    purple_request_close(PURPLE_REQUEST_FIELDS, user_data);
+    return FALSE;
+}
+
+/*
+ * We must support purple_account_request_password() which boils down
+ * to purple_request_fields() with certain parameters. I'm not sure
+ * if this the best way of doing this, but it works.
+ */
 static gpointer
 haze_request_fields (const char *title,
                      const char *primary,
@@ -138,33 +157,34 @@ haze_request_fields (const char *title,
                      PurpleConversation *conv,
                      void *user_data)
 {
-    /*
-     * We must support purple_account_request_password() which boils down
-     * to purple_request_fields() with certain parameters. I'm not sure
-     * if this the best way of doing this, but it works.
-     */
+    struct fields_data *fd = g_new0(struct fields_data, 1);
+
+    /* it is our responsibility to destroy this data */
+    fd->fields = fields;
+
     if (purple_request_fields_exists(fields, "password") &&
         purple_request_fields_exists(fields, "remember")) {
-        struct password_data *pd = g_new0(struct password_data, 1);
 
         DEBUG ("triggering password request");
 
-        pd->fields    = fields;
-        pd->password  = purple_request_fields_get_field(fields, "password");
-        pd->ok_cb     = ok_cb;
-        pd->cancel_cb = cancel_cb;
-        pd->user_data = user_data;
+        fd->password  = purple_request_fields_get_field(fields, "password");
+        fd->ok_cb     = ok_cb;
+        fd->cancel_cb = cancel_cb;
+        fd->user_data = user_data;
 
-        haze_connection_request_password(account, pd);
+        haze_connection_request_password(account, fd);
 
     } else {
         DEBUG ("ignoring request:");
         DEBUG ("    title: %s", (title ? title : "(null)"));
         DEBUG ("    primary: %s", (primary ? primary : "(null)"));
         DEBUG ("    secondary: %s", (secondary ? secondary : "(null)"));
+
+	/* Avoid leaking of "fields" */
+	g_idle_add(haze_request_fields_destroy, fd);
     }
 
-    return NULL;
+    return fd;
 }
 
 #ifdef ENABLE_LEAKY_REQUEST_STUBS
@@ -204,10 +224,6 @@ haze_request_folder (const char *title,
 }
 #endif
 
-/*
-	void (*close_request)(PurpleRequestType type, void *ui_handle);
-*/
-
 static PurpleRequestUiOps request_uiops =
 {
 #ifdef ENABLE_LEAKY_REQUEST_STUBS
@@ -217,7 +233,8 @@ static PurpleRequestUiOps request_uiops =
     .request_file = haze_request_file,
     .request_folder = haze_request_folder,
 #endif
-    .request_fields = haze_request_fields
+    .request_fields = haze_request_fields,
+    .close_request  = haze_close_request
 };
 
 PurpleRequestUiOps *



More information about the telepathy-commits mailing list