aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordequis <dx@dxzone.com.ar>2016-10-08 03:32:08 -0300
committerdequis <dx@dxzone.com.ar>2016-10-08 03:39:05 -0300
commit01d56c0c47f4d4642be4224b43c403918f3d4372 (patch)
tree20b99206f58d0326acb291cba4993321c507eb54
parent58d285a4eec4f921be9de3c51341ef3d8729a999 (diff)
purple: Fix handling of empty, immediate roomlist results
Two issues here: 1. SIPE called in_progress(FALSE) immediately (which decreases refcount), before purple_roomlist_get_list() could return (which would normally increase refcount). The first refcount decrease steals it from the prpl, and bad things happen. Added an initialized flag to only do that decrease after it was increased first. This is similar to how pidgin sets a 'dialog' attribute after the purple_roomlist_get_list() call, and skips the unref if it's not set. 2. The code assumed that NULL return value means room listing not supported. That's not quite true, so now it checks in the prpl info to see if roomlist_get_list is defined. Also, made purple_roomlist_data more private.
-rw-r--r--protocols/purple/bpurple.h6
-rw-r--r--protocols/purple/purple.c26
2 files changed, 22 insertions, 10 deletions
diff --git a/protocols/purple/bpurple.h b/protocols/purple/bpurple.h
index ca7cf70e..39677b86 100644
--- a/protocols/purple/bpurple.h
+++ b/protocols/purple/bpurple.h
@@ -14,10 +14,4 @@ struct purple_data
guint next_request_id;
};
-struct purple_roomlist_data
-{
- GSList *chats;
- gint topic;
-};
-
#endif /* !BPURPLE_H */
diff --git a/protocols/purple/purple.c b/protocols/purple/purple.c
index 374b826b..6b043101 100644
--- a/protocols/purple/purple.c
+++ b/protocols/purple/purple.c
@@ -53,6 +53,13 @@ struct request_input_data {
guint id;
};
+struct purple_roomlist_data {
+ GSList *chats;
+ gint topic;
+ gboolean initialized;
+};
+
+
struct im_connection *purple_ic_by_pa(PurpleAccount *pa)
{
GSList *i;
@@ -770,13 +777,21 @@ void purple_chat_list(struct im_connection *ic, const char *server)
{
PurpleRoomlist *list;
struct purple_data *pd = ic->proto_data;
+ PurplePlugin *prpl = purple_plugins_find_with_id(pd->account->protocol_id);
+ PurplePluginProtocolInfo *pi = prpl->info->extra_info;
+
+ if (!pi || !pi->roomlist_get_list) {
+ imcb_log(ic, "Room listing unsupported by this purple plugin");
+ return;
+ }
list = purple_roomlist_get_list(pd->account->gc);
if (list) {
+ struct purple_roomlist_data *rld = list->ui_data;
+ rld->initialized = TRUE;
+
purple_roomlist_ref(list);
- } else {
- imcb_log(ic, "Room listing unsupported by this purple plugin");
}
}
@@ -1381,7 +1396,7 @@ static void prplcb_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progre
struct im_connection *ic;
struct purple_roomlist_data *rld = list->ui_data;
- if (in_progress) {
+ if (in_progress || !rld) {
return;
}
@@ -1392,7 +1407,10 @@ static void prplcb_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progre
rld->chats = NULL;
bee_chat_list_finish(ic);
- purple_roomlist_unref(list);
+
+ if (rld->initialized) {
+ purple_roomlist_unref(list);
+ }
}
static void prplcb_roomlist_destroy(PurpleRoomlist *list)