summaryrefslogtreecommitdiff
path: root/daemon/gvfschannel.c
diff options
context:
space:
mode:
authorRoss Lagerwall <rosslagerwall@gmail.com>2015-02-05 23:49:29 +0000
committerRoss Lagerwall <rosslagerwall@gmail.com>2015-02-10 19:50:10 +0000
commit46b8a4516b2cc66cfa043d187777c223a32d4df3 (patch)
treea8336fe942fe195f6fc611f4d0aec7c1a7642246 /daemon/gvfschannel.c
parentaaa86631787bb010af12e62ffd85877d72813509 (diff)
downloadgvfs-46b8a4516b2cc66cfa043d187777c223a32d4df3.tar.gz
channel: Fix a couple of leaks
Fix leaks when sending a GFileInfo through a channel or sending an error. This can be seen by running gvfsd through valgrind and doing query_info_on_{read,write} or truncating with a negative size. https://bugzilla.gnome.org/show_bug.cgi?id=744078
Diffstat (limited to 'daemon/gvfschannel.c')
-rw-r--r--daemon/gvfschannel.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/daemon/gvfschannel.c b/daemon/gvfschannel.c
index 90b7b5a1..021d292a 100644
--- a/daemon/gvfschannel.c
+++ b/daemon/gvfschannel.c
@@ -100,7 +100,10 @@ struct _GVfsChannelPrivate
char reply_buffer[G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE];
int reply_buffer_pos;
- const char *output_data; /* Owned by job */
+ /* output_data is owned by the channel if output_data_free is set,
+ * otherwise it is owned by the job. */
+ const char *output_data;
+ char *output_data_free;
gsize output_data_size;
gsize output_data_pos;
};
@@ -599,6 +602,11 @@ send_reply_cb (GObject *source_object,
error_out:
/* Sent full reply */
+ if (channel->priv->output_data_free)
+ {
+ g_free (channel->priv->output_data_free);
+ channel->priv->output_data_free = NULL;
+ }
channel->priv->output_data = NULL;
job = channel->priv->current_job;
@@ -670,6 +678,17 @@ g_vfs_channel_send_reply (GVfsChannel *channel,
}
}
+/* Might be called on an i/o thread */
+void
+g_vfs_channel_send_reply_take (GVfsChannel *channel,
+ GVfsDaemonSocketProtocolReply *reply,
+ void *data,
+ gsize data_len)
+{
+ channel->priv->output_data_free = data;
+ g_vfs_channel_send_reply (channel, reply, data, data_len);
+}
+
/* Might be called on an i/o thread
*/
void
@@ -680,7 +699,7 @@ g_vfs_channel_send_error (GVfsChannel *channel,
gsize data_len;
data = g_error_to_daemon_reply (error, channel->priv->current_job_seq_nr, &data_len);
- g_vfs_channel_send_reply (channel, NULL, data, data_len);
+ g_vfs_channel_send_reply_take (channel, NULL, data, data_len);
}
/* Might be called on an i/o thread
@@ -700,7 +719,7 @@ g_vfs_channel_send_info (GVfsChannel *channel,
reply.arg1 = 0;
reply.arg2 = g_htonl (data_len);
- g_vfs_channel_send_reply (channel, &reply, data, data_len);
+ g_vfs_channel_send_reply_take (channel, &reply, data, data_len);
}
int