From e41ba62a88ebb0112639ab568f5e9bb43d8c95f8 Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Mon, 3 Mar 2014 21:34:10 +0200 Subject: [PATCH] purple: fix crash on call initiation failure sipe_backend_media_free() did not disconnect the callbacks. That could lead to callbacks being called after all data structures have already been invalidated. Crash reported in Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1071710 --- src/purple/purple-media.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/purple/purple-media.c b/src/purple/purple-media.c index dd179d13..c61208b9 100644 --- a/src/purple/purple-media.c +++ b/src/purple/purple-media.c @@ -3,7 +3,7 @@ * * pidgin-sipe * - * Copyright (C) 2010-12 SIPE Project + * Copyright (C) 2010-2014 SIPE Project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,6 +61,7 @@ #include "media-gst.h" struct sipe_backend_media { + struct sipe_media_call *call; PurpleMedia *m; GSList *streams; /** @@ -239,10 +240,11 @@ sipe_backend_media_new(struct sipe_core_public *sipe_public, PurpleMediaManager *manager = purple_media_manager_get(); GstElement *pipeline; - media->m = purple_media_manager_create_media(manager, - purple_private->account, - "fsrtpconference", - participant, initiator); + media->call = call; + media->m = purple_media_manager_create_media(manager, + purple_private->account, + "fsrtpconference", + participant, initiator); g_signal_connect(G_OBJECT(media->m), "candidates-prepared", G_CALLBACK(on_candidates_prepared_cb), call); @@ -270,6 +272,24 @@ sipe_backend_media_free(struct sipe_backend_media *media) { if (media) { GSList *stream = media->streams; + PurpleMediaManager *manager = purple_media_manager_get(); + + g_signal_handlers_disconnect_by_func(G_OBJECT(media->m), + G_CALLBACK(on_candidates_prepared_cb), + media->call); + g_signal_handlers_disconnect_by_func(G_OBJECT(media->m), + G_CALLBACK(on_codecs_changed_cb), + media->call); + g_signal_handlers_disconnect_by_func(G_OBJECT(media->m), + G_CALLBACK(on_stream_info_cb), + media->call); + g_signal_handlers_disconnect_by_func(G_OBJECT(media->m), + G_CALLBACK(on_error_cb), + media->call); + g_signal_handlers_disconnect_by_func(G_OBJECT(media->m), + G_CALLBACK(on_state_changed_cb), + media->call); + purple_media_manager_remove_media(manager, media->m); for (; stream; stream = g_slist_delete_link(stream, stream)) backend_stream_free(stream->data); -- 2.11.4.GIT