diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2011-10-04 15:05:11 +0100 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2011-10-04 15:05:12 +0100 |
commit | 1c1c688e8c6ceda679c1473c7454ee6db2710007 (patch) | |
tree | 05839843f8d3b6e855e33d6f2eb12ea889fbb101 | |
parent | a899ab819ccb3f60b083822eedb0f7989bee3707 (diff) | |
parent | dff3ce56fe82a9b16068d0cdcbc508d2d3c390ba (diff) |
Merge branch '40523-crash-on-ack' into telepathy-glib-0.14
Reviewed-by: Xavier Claessens <xclaesse@gmail.com>
-rw-r--r-- | telepathy-glib/message-mixin.c | 39 | ||||
-rw-r--r-- | tests/dbus/message-mixin.c | 8 |
2 files changed, 35 insertions, 12 deletions
diff --git a/telepathy-glib/message-mixin.c b/telepathy-glib/message-mixin.c index 8bfc6dc05..e1ffee788 100644 --- a/telepathy-glib/message-mixin.c +++ b/telepathy-glib/message-mixin.c @@ -55,6 +55,7 @@ #include <telepathy-glib/message-mixin.h> #include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> #include <string.h> #include <telepathy-glib/cm-message.h> @@ -389,19 +390,30 @@ tp_message_mixin_acknowledge_pending_messages_async ( DBusGMethodInvocation *context) { TpMessageMixin *mixin = TP_MESSAGE_MIXIN (iface); - GList **nodes; + GPtrArray *links = g_ptr_array_sized_new (ids->len); + TpIntset *seen = tp_intset_new (); guint i; - nodes = g_new (GList *, ids->len); - for (i = 0; i < ids->len; i++) { guint id = g_array_index (ids, guint, i); + GList *link_; + + if (tp_intset_is_member (seen, id)) + { + gchar *client = dbus_g_method_get_sender (context); - nodes[i] = g_queue_find_custom (mixin->priv->pending, + DEBUG ("%s passed message id %u more than once in one call to " + "AcknowledgePendingMessages. Foolish pup.", client, id); + g_free (client); + continue; + } + + tp_intset_add (seen, id); + link_ = g_queue_find_custom (mixin->priv->pending, GUINT_TO_POINTER (id), pending_item_id_equals_data); - if (nodes[i] == NULL) + if (link_ == NULL) { GError *error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "invalid message id %u", id); @@ -410,28 +422,33 @@ tp_message_mixin_acknowledge_pending_messages_async ( dbus_g_method_return_error (context, error); g_error_free (error); - g_free (nodes); + g_ptr_array_unref (links); + tp_intset_destroy (seen); return; } + + g_ptr_array_add (links, link_); } tp_svc_channel_interface_messages_emit_pending_messages_removed (iface, ids); - for (i = 0; i < ids->len; i++) + for (i = 0; i < links->len; i++) { - TpMessage *item = nodes[i]->data; + GList *link_ = g_ptr_array_index (links, i); + TpMessage *item = link_->data; #ifdef ENABLE_DEBUG - TpCMMessage *cm_msg = nodes[i]->data; + TpCMMessage *cm_msg = link_->data; #endif DEBUG ("acknowledging message id %u", cm_msg->incoming_id); - g_queue_remove (mixin->priv->pending, item); + g_queue_delete_link (mixin->priv->pending, link_); tp_message_destroy (item); } - g_free (nodes); + g_ptr_array_unref (links); + tp_intset_destroy (seen); tp_svc_channel_type_text_return_from_acknowledge_pending_messages (context); } diff --git a/tests/dbus/message-mixin.c b/tests/dbus/message-mixin.c index 938981f46..2d499c316 100644 --- a/tests/dbus/message-mixin.c +++ b/tests/dbus/message-mixin.c @@ -1043,9 +1043,15 @@ main (int argc, g_print ("\n\n==== Acknowledging one message ====\n"); { - GArray *msgid = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); + /* As a regression test for + * <https://bugs.freedesktop.org/show_bug.cgi?id=40523>, we include the + * ID of the message we want to ack twice. This used to cause a + * double-free. + */ + GArray *msgid = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2); g_array_append_val (msgid, last_received_id); + g_array_append_val (msgid, last_received_id); tp_cli_channel_type_text_run_acknowledge_pending_messages (chan, -1, msgid, &error, NULL); |