[gvfs] afp: fix some memoryleaks



commit e83e66caff7b8084b575c5fa38219b40c6c377b3
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date:   Sun Aug 14 14:57:54 2011 +0200

    afp: fix some memoryleaks
    
    change g_vfs_afp_connection_send_command to take a "char *reply_buf" paramater
    to use for storing the reply data instead of reusing the buf data pointer in
    GVfsAfpCommand

 daemon/gvfsafpconnection.c    |   98 ++++++++++++++++++++--------------------
 daemon/gvfsafpconnection.h    |    1 +
 daemon/gvfsafpserver.c        |    6 ++-
 daemon/gvfsbackendafp.c       |   44 +++++++++----------
 daemon/gvfsbackendafpbrowse.c |    2 +-
 5 files changed, 76 insertions(+), 75 deletions(-)
---
diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c
index 4c369a8..b725f54 100644
--- a/daemon/gvfsafpconnection.c
+++ b/daemon/gvfsafpconnection.c
@@ -88,6 +88,7 @@ struct _GVfsAfpReply
 
   char *data;
   gsize len;
+  gboolean free_data;
 
   goffset pos;
 };
@@ -103,12 +104,24 @@ g_vfs_afp_reply_init (GVfsAfpReply *reply)
 }
 
 static void
+g_vfs_afp_reply_finalize (GObject *object)
+{
+  GVfsAfpReply *reply = (GVfsAfpReply *)object;
+
+  if (reply->free_data)
+    g_free (reply->data);
+}
+
+static void
 g_vfs_afp_reply_class_init (GVfsAfpReplyClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = g_vfs_afp_reply_finalize;
 }
 
 static GVfsAfpReply *
-g_vfs_afp_reply_new (AfpResultCode result_code, char *data, gsize len)
+g_vfs_afp_reply_new (AfpResultCode result_code, char *data, gsize len, gboolean take_data)
 {
   GVfsAfpReply *reply;
 
@@ -117,6 +130,7 @@ g_vfs_afp_reply_new (AfpResultCode result_code, char *data, gsize len)
   reply->result_code = result_code;
   reply->len = len;
   reply->data = data;
+  reply->free_data = take_data;
   
   return reply;
 }
@@ -407,11 +421,15 @@ g_vfs_afp_command_class_init (GVfsAfpCommandClass *klass)
 GVfsAfpCommand *
 g_vfs_afp_command_new (AfpCommandType type)
 {
+  GOutputStream *mem_stream;
   GVfsAfpCommand *comm;
 
+  mem_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
   comm = g_object_new (G_VFS_TYPE_AFP_COMMAND,
-                       "base-stream", g_memory_output_stream_new (NULL, 0, g_realloc, g_free),
+                       "base-stream", mem_stream,
                        NULL);
+
+  g_object_unref (mem_stream);
   
   comm->type = type;
   g_vfs_afp_command_put_byte (comm, type);
@@ -569,7 +587,8 @@ struct _GVfsAfpConnectionPrivate
   /* read loop */
   gboolean read_loop_running;
   DSIHeader read_dsi_header;
-  char *data;
+  char *reply_buf;
+  gboolean free_reply_buf;
 };
 
 typedef enum
@@ -605,6 +624,7 @@ typedef struct
   RequestType type;
   
   GVfsAfpCommand *command;
+  char           *reply_buf;
   GSimpleAsyncResult *simple;
   GCancellable *cancellable;
 } RequestData;
@@ -778,10 +798,9 @@ dispatch_reply (GVfsAfpConnection *afp_connection)
     {
       guint8 attention_code;
 
-      attention_code = priv->data[0] >> 4;
+      attention_code = priv->reply_buf[0] >> 4;
 
       g_signal_emit (afp_connection, signals[ATTENTION], 0, attention_code);
-      g_free (priv->data);
       break;
     }
 
@@ -796,8 +815,9 @@ dispatch_reply (GVfsAfpConnection *afp_connection)
       {
         GVfsAfpReply *reply;
 
-        reply = g_vfs_afp_reply_new (dsi_header->errorCode, priv->data,
-                                     dsi_header->totalDataLength);
+        reply = g_vfs_afp_reply_new (dsi_header->errorCode, priv->reply_buf,
+                                     dsi_header->totalDataLength, priv->free_reply_buf);
+        priv->free_reply_buf = FALSE;
 
         g_simple_async_result_set_op_res_gpointer (req_data->simple, reply,
                                                    g_object_unref);
@@ -806,9 +826,6 @@ dispatch_reply (GVfsAfpConnection *afp_connection)
         g_hash_table_remove (priv->request_hash,
                              GUINT_TO_POINTER ((guint)dsi_header->requestID));
       }
-      else
-        g_free (priv->data);
-      
       break;
     }
 
@@ -816,31 +833,13 @@ dispatch_reply (GVfsAfpConnection *afp_connection)
       g_assert_not_reached ();
   }
 }
-
-static void
-skip_data_cb (GObject *object, GAsyncResult *res, gpointer user_data)
-{
-  GInputStream *input = G_INPUT_STREAM (object);
-  GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data);
-
-  gsize bytes_skipped;
-  GError *err = NULL;
-
-  bytes_skipped = g_input_stream_skip_finish (input, res, &err);
-  if (bytes_skipped == -1)
-  {
-    g_warning ("FAIL!!! \"%s\"\n", err->message);
-    g_error_free (err);
-  }
-
-  read_reply (afp_connection);
-}
     
 static void
 read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 {
   GInputStream *input = G_INPUT_STREAM (object);
   GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data);
+  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
   gboolean result;
   GError *err = NULL;
@@ -853,6 +852,10 @@ read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data)
   }
 
   dispatch_reply (afp_connection);
+
+  if (priv->free_reply_buf)
+    g_free (priv->reply_buf);
+  
   read_reply (afp_connection);
 }
 
@@ -886,23 +889,20 @@ read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 
     req_data = g_hash_table_lookup (priv->request_hash,
                                     GUINT_TO_POINTER ((guint)dsi_header->requestID));
-    if (req_data)
+    if (req_data && req_data->reply_buf)
     {
-      if (req_data->command->type == AFP_COMMAND_READ_EXT && req_data->command->buf)
-        priv->data = req_data->command->buf;
-      else
-        priv->data = g_malloc (dsi_header->totalDataLength);
-
-      read_all_async (input, priv->data, dsi_header->totalDataLength,
-                      0, NULL, read_data_cb, afp_conn);
+        priv->reply_buf = req_data->reply_buf;
+        priv->free_reply_buf = FALSE;
     }
     else
     {
-      /* TODO: should really do a skip_all */
-      g_input_stream_skip_async (input, dsi_header->totalDataLength, 0, NULL,
-                                 skip_data_cb, afp_conn);
+      priv->reply_buf = g_malloc (dsi_header->totalDataLength);
+      priv->free_reply_buf = TRUE;
     }
     
+    read_all_async (input, priv->reply_buf, dsi_header->totalDataLength,
+                    0, NULL, read_data_cb, afp_conn);
+    
     return;
   }
 
@@ -919,8 +919,6 @@ read_reply (GVfsAfpConnection *afp_connection)
 
   input = g_io_stream_get_input_stream (priv->conn);
   
-  priv->data = NULL;
-
   read_all_async (input, &priv->read_dsi_header, sizeof (DSIHeader), 0, NULL,
                   read_dsi_header_cb, afp_connection);
 }
@@ -1236,11 +1234,12 @@ send_request (GVfsAfpConnection *afp_connection)
 }
 
 void
-g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection,
-                                   GVfsAfpCommand *command,
-                                   GAsyncReadyCallback callback,
-                                   GCancellable *cancellable,
-                                   gpointer user_data)
+g_vfs_afp_connection_send_command (GVfsAfpConnection   *afp_connection,
+                                   GVfsAfpCommand      *command,
+                                   char                *reply_buf,
+                                   GAsyncReadyCallback  callback,
+                                   GCancellable        *cancellable,
+                                   gpointer             user_data)
 {
   GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
@@ -1249,6 +1248,7 @@ g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection,
   req_data = g_slice_new0 (RequestData);
   req_data->type = REQUEST_TYPE_COMMAND;
   req_data->command = g_object_ref (command);
+  req_data->reply_buf = reply_buf;
 
   req_data->simple = g_simple_async_result_new (G_OBJECT (afp_connection), callback,
                                                 user_data,
@@ -1352,7 +1352,7 @@ g_vfs_afp_connection_read_reply_sync (GVfsAfpConnection *afp_connection,
   if (!res)
     return NULL;
 
-  return g_vfs_afp_reply_new (dsi_header.errorCode, data, dsi_header.totalDataLength);
+  return g_vfs_afp_reply_new (dsi_header.errorCode, data, dsi_header.totalDataLength, TRUE);
 }
 
 static gboolean
@@ -1569,7 +1569,7 @@ g_vfs_afp_connection_get_server_info (GVfsAfpConnection *afp_connection,
   g_object_unref (conn);
   
   return g_vfs_afp_reply_new (dsi_header.errorCode, data,
-                              dsi_header.totalDataLength);
+                              dsi_header.totalDataLength, TRUE);
 }
 
 GVfsAfpConnection *
diff --git a/daemon/gvfsafpconnection.h b/daemon/gvfsafpconnection.h
index 97c8584..cabfa89 100644
--- a/daemon/gvfsafpconnection.h
+++ b/daemon/gvfsafpconnection.h
@@ -400,6 +400,7 @@ GVfsAfpReply*      g_vfs_afp_connection_send_command_finish (GVfsAfpConnection *
 
 void               g_vfs_afp_connection_send_command     (GVfsAfpConnection   *afp_connection,
                                                           GVfsAfpCommand      *command,
+                                                          char                *reply_buf,
                                                           GAsyncReadyCallback  callback,
                                                           GCancellable        *cancellable,                                                           
                                                           gpointer             user_data);
diff --git a/daemon/gvfsafpserver.c b/daemon/gvfsafpserver.c
index a14f2e7..2a31d46 100644
--- a/daemon/gvfsafpserver.c
+++ b/daemon/gvfsafpserver.c
@@ -108,8 +108,8 @@ attention_cb (GVfsAfpConnection *conn, guint attention_code, gpointer user_data)
     /* MessageBitmap */
     g_vfs_afp_command_put_int16 (comm, 1);
 
-    g_vfs_afp_connection_send_command (afp_serv->conn, comm, get_srvr_msg_cb,
-                                       NULL, afp_serv);
+    g_vfs_afp_connection_send_command (afp_serv->conn, comm, NULL,
+                                       get_srvr_msg_cb, NULL, afp_serv);
     g_object_unref (comm);
   }
 }
@@ -419,6 +419,7 @@ cleanup:
   gcry_mpi_release (p);
   gcry_mpi_release (Ma);
   gcry_mpi_release (Mb);
+  gcry_mpi_release (Ra);
   gcry_mpi_release (key);
   gcry_mpi_release (clientNonce);
   gcry_mpi_release (clientNonce1);
@@ -824,6 +825,7 @@ get_server_info (GVfsAfpServer *afp_serv,
     afp_serv->uams = g_slist_prepend (afp_serv->uams, uam);
   }
 
+  g_object_unref (reply);
   
   return TRUE;
 }
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c
index e63eade..288e34c 100644
--- a/daemon/gvfsbackendafp.c
+++ b/daemon/gvfsbackendafp.c
@@ -517,7 +517,7 @@ open_fork (GVfsBackendAfp     *afp_backend,
   simple = g_simple_async_result_new (G_OBJECT (afp_backend), callback,
                                       user_data, open_fork);
   
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                      open_fork_cb, cancellable, simple);
   g_object_unref (comm);
 }
@@ -595,7 +595,7 @@ close_fork (GVfsBackendAfp    *afp_backend,
   simple = g_simple_async_result_new (G_OBJECT (afp_backend), callback, user_data,
                                       close_fork);
   
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                       close_fork_cb, cancellable,
                                       simple);
   g_object_unref (comm);
@@ -689,7 +689,7 @@ get_fork_parms (GVfsBackendAfp      *afp_backend,
                                       get_fork_parms);
                                       
   
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                       get_fork_parms_cb, cancellable,
                                       simple);
   g_object_unref (comm);
@@ -809,7 +809,7 @@ get_filedir_parms (GVfsBackendAfp      *afp_backend,
                                       get_filedir_parms);
                                       
 
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                      get_filedir_parms_cb, cancellable,
                                      simple);
   g_object_unref (comm);
@@ -947,7 +947,7 @@ get_vol_parms (GVfsBackendAfp      *afp_backend,
                                       get_vol_parms);
                                       
   
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                       get_vol_parms_cb, cancellable,
                                       simple);
   g_object_unref (comm);
@@ -1090,8 +1090,8 @@ create_file_get_filedir_parms_cb (GObject *source_object, GAsyncResult *res, gpo
   put_pathname (comm, basename);
   g_free (basename);
 
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, create_file_cb,
-                                     cfd->cancellable, cfd);
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
+                                     create_file_cb, cfd->cancellable, cfd);
   g_object_unref (comm);
 }
 
@@ -1225,8 +1225,8 @@ delete (GVfsBackendAfp      *afp_backend,
   simple = g_simple_async_result_new (G_OBJECT (afp_backend), callback,
                                       user_data, delete);
   
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, delete_cb,
-                                     cancellable, simple);
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
+                                     delete_cb, cancellable, simple);
   g_object_unref (comm);
 }
 
@@ -1349,7 +1349,7 @@ move (GVfsBackendAfp *afp_backend, GVfsJobMove *job)
   put_pathname (comm, basename);
   g_free (basename);
 
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                      move_and_rename_cb, G_VFS_JOB (job)->cancellable,
                                      job);
   g_object_unref (comm);
@@ -1621,8 +1621,8 @@ set_display_name_get_filedir_parms_cb (GObject      *source_object,
   /* NewName */
   put_pathname (comm, job->display_name);
 
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, rename_cb,
-                                     G_VFS_JOB (job)->cancellable, job);
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
+                                     rename_cb, G_VFS_JOB (job)->cancellable, job);
   g_object_unref (comm);
 }
   
@@ -1745,7 +1745,8 @@ make_directory_get_filedir_parms_cb (GObject *source_object, GAsyncResult *res,
   put_pathname (comm, basename);
   g_free (basename);
 
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, make_directory_cb,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
+                                     make_directory_cb,
                                      G_VFS_JOB (job)->cancellable, job);
   g_object_unref (comm);
 }
@@ -1883,7 +1884,7 @@ try_write (GVfsBackend *backend,
 
   g_vfs_afp_command_set_buffer (comm, buffer, buffer_size);
 
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                      write_ext_cb, G_VFS_JOB (job)->cancellable,
                                      job);
   g_object_unref (comm);
@@ -2116,10 +2117,7 @@ try_read (GVfsBackend *backend,
   req_count = MIN (bytes_requested, G_MAXUINT32);
   g_vfs_afp_command_put_int64 (comm, req_count);
 
-  /* Set buffer to read into */
-  g_vfs_afp_command_set_buffer (comm, buffer, bytes_requested);
-  
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, buffer,
                                       read_ext_cb, G_VFS_JOB (job)->cancellable,
                                       job);
   g_object_unref (comm);
@@ -2148,7 +2146,7 @@ close_replace_close_fork_cb (GObject *source_object, GAsyncResult *res, gpointer
   put_pathname (comm, afp_handle->tmp_filename);
 
   g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
-                                      NULL, NULL);
+                                     NULL, NULL, NULL);
   g_object_unref (comm);
   
 
@@ -2301,7 +2299,7 @@ try_close_write (GVfsBackend *backend,
     /* DestPath */
     put_pathname (comm, afp_handle->tmp_filename);
 
-    g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+    g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                        close_replace_exchange_files_cb,
                                        G_VFS_JOB (job)->cancellable, job);
     g_object_unref (comm);
@@ -2321,7 +2319,7 @@ try_close_write (GVfsBackend *backend,
     /* ForkLen */
     g_vfs_afp_command_put_int64 (comm, afp_handle->size);
 
-    g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+    g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                        close_replace_set_fork_parms_cb,
                                        G_VFS_JOB (job)->cancellable, job);
     g_object_unref (comm);
@@ -2893,7 +2891,7 @@ enumerate (GVfsBackendAfp *afp_backend,
   g_object_set_data (G_OBJECT (job), "start-index",
                      GINT_TO_POINTER (start_index));
   
-  g_vfs_afp_connection_send_command (conn, comm, enumerate_cb,
+  g_vfs_afp_connection_send_command (conn, comm, NULL, enumerate_cb,
                                      G_VFS_JOB (job)->cancellable, job);
   g_object_unref (comm);
 }
@@ -3057,7 +3055,7 @@ set_attribute_get_filedir_parms_cb (GObject *source_object, GAsyncResult *res, g
   /* UAPermissions */
   g_vfs_afp_command_put_uint32 (comm, ua_permissions);
 
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                      set_attribute_set_filedir_parms_cb,
                                      G_VFS_JOB (job)->cancellable, job);
   g_object_unref (comm);
diff --git a/daemon/gvfsbackendafpbrowse.c b/daemon/gvfsbackendafpbrowse.c
index bec88f5..bf54a6d 100644
--- a/daemon/gvfsbackendafpbrowse.c
+++ b/daemon/gvfsbackendafpbrowse.c
@@ -170,7 +170,7 @@ update_cache (GVfsBackendAfpBrowse *afp_backend,
   simple = g_simple_async_result_new (G_OBJECT (afp_backend), callback,
                                       user_data, update_cache);
   
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
                                      get_srvr_parms_cb,
                                      cancellable, simple);
   g_object_unref (comm); 



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