pidgin: 6de8f788: Use ref-counting to prevent a crash if r...
sadrul at pidgin.im
sadrul at pidgin.im
Thu Dec 11 16:10:38 EST 2008
-----------------------------------------------------------------
Revision: 6de8f788571b507b2c76125cc65f88db49c60790
Ancestor: 2b3429067be9bc2eb9be9e8deeeac9c35001f61d
Author: sadrul at pidgin.im
Date: 2008-12-11T21:10:57
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/6de8f788571b507b2c76125cc65f88db49c60790
Modified files:
libpurple/account.c
ChangeLog:
Use ref-counting to prevent a crash if request-auth callbacks are called
immediately/synchronously. Thanks a lot to Florian Qu?ze for the initial
patch, and for testing the alternate fix. Closes #7604.
-------------- next part --------------
============================================================
--- libpurple/account.c d59224845aa473b7aeb4ebc5dbbb0a1dccfa21c3
+++ libpurple/account.c 2d7a963bb5083959e2898e9ad47a372d6c125309
@@ -75,6 +75,7 @@ typedef struct
gpointer userdata;
PurpleAccountRequestAuthorizationCb auth_cb;
PurpleAccountRequestAuthorizationCb deny_cb;
+ guint ref;
} PurpleAccountRequestInfo;
static PurpleAccountUiOps *account_ui_ops = NULL;
@@ -1211,6 +1212,18 @@ purple_account_request_add(PurpleAccount
ui_ops->request_add(account, remote_user, id, alias, message);
}
+static PurpleAccountRequestInfo *
+purple_account_request_info_unref(PurpleAccountRequestInfo *info)
+{
+ if (--info->ref)
+ return info;
+
+ /* TODO: This will leak info->user_data, but there is no callback to just clean that up */
+ g_free(info->user);
+ g_free(info);
+ return NULL;
+}
+
static void
purple_account_request_close_info(PurpleAccountRequestInfo *info)
{
@@ -1221,11 +1234,7 @@ purple_account_request_close_info(Purple
if (ops != NULL && ops->close_account_request != NULL)
ops->close_account_request(info->ui_handle);
- /* TODO: This will leak info->user_data, but there is no callback to just clean that up */
-
- g_free(info->user);
- g_free(info);
-
+ purple_account_request_info_unref(info);
}
void
@@ -1278,8 +1287,7 @@ request_auth_cb(void *data)
purple_signal_emit(purple_accounts_get_handle(),
"account-authorization-granted", info->account, info->user);
- g_free(info->user);
- g_free(info);
+ purple_account_request_info_unref(info);
}
static void
@@ -1294,8 +1302,7 @@ request_deny_cb(void *data)
purple_signal_emit(purple_accounts_get_handle(),
"account-authorization-denied", info->account, info->user);
- g_free(info->user);
- g_free(info);
+ purple_account_request_info_unref(info);
}
void *
@@ -1332,11 +1339,18 @@ purple_account_request_authorization(Pur
info->deny_cb = deny_cb;
info->userdata = user_data;
info->user = g_strdup(remote_user);
+ info->ref = 2; /* We hold an extra ref to make sure info remains valid
+ if any of the callbacks are called synchronously. We
+ unref it after the function call */
+
info->ui_handle = ui_ops->request_authorize(account, remote_user, id, alias, message,
on_list, request_auth_cb, request_deny_cb, info);
- handles = g_list_append(handles, info);
- return info->ui_handle;
+ info = purple_account_request_info_unref(info);
+ if (info) {
+ handles = g_list_append(handles, info);
+ return info->ui_handle;
+ }
}
return NULL;
More information about the Commits
mailing list