Changeset 2c5ab49


Ignore:
Timestamp:
2015-03-15T04:34:43Z (10 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
2dd23da
Parents:
6a48992
git-author:
dequis <dx@…> (14-03-15 01:03:43)
git-committer:
dequis <dx@…> (15-03-15 04:34:43)
Message:

purple: prplcb_close_request() improvements

  • Added support for PURPLE_REQUEST_INPUT
  • Changed memory management to do the free() of data through purple_request_close(), letting purple know that the request was answered, and fixing use-after-free issues with it
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/purple/purple.c

    r6a48992 r2c5ab49  
    4949        ri_callback_t data_callback;
    5050        void *user_data;
     51        struct im_connection *ic;
     52        char *buddy;
     53        guint id;
    5154};
    5255
     
    10171020                pqad->yes(pqad->user_data, pqad->yes_i);
    10181021        }
    1019         g_free(pqad);
    10201022}
    10211023
     
    10271029                pqad->no(pqad->user_data, pqad->no_i);
    10281030        }
    1029         g_free(pqad);
     1031}
     1032
     1033/* q->free() callback from query_del()*/
     1034static void prplcb_request_action_free(void *data)
     1035{
     1036        struct prplcb_request_action_data *pqad = data;
     1037
     1038        pqad->bee_data = NULL;
     1039        purple_request_close(PURPLE_REQUEST_ACTION, pqad);
    10301040}
    10311041
     
    10621072        q = g_strdup_printf("Request: %s\n\n%s\n\n%s", title, primary, secondary);
    10631073        pqad->bee_data = query_add(local_bee->ui_data, purple_ic_by_pa(account), q,
    1064                                    prplcb_request_action_yes, prplcb_request_action_no, g_free, pqad);
     1074                                   prplcb_request_action_yes, prplcb_request_action_no,
     1075                                   prplcb_request_action_free, pqad);
    10651076
    10661077        g_free(q);
     
    10751086static void prplcb_close_request(PurpleRequestType type, void *data)
    10761087{
    1077         if (type == PURPLE_REQUEST_ACTION) {
    1078                 struct prplcb_request_action_data *pqad = data;
    1079                 query_del(local_bee->ui_data, pqad->bee_data);
    1080         }
    1081         /* Add the request input handler here when that becomes a thing */
    1082 }
    1083 
    1084 /*
    1085 static void prplcb_request_test()
    1086 {
    1087         fprintf( stderr, "bla\n" );
    1088 }
    1089 */
     1088        struct prplcb_request_action_data *pqad;
     1089        struct request_input_data *ri;
     1090        struct purple_data *pd;
     1091
     1092        if (!data) {
     1093                return;
     1094        }
     1095
     1096        switch (type) {
     1097        case PURPLE_REQUEST_ACTION:
     1098                pqad = data;
     1099                /* if this is null, it's because query_del was run already */
     1100                if (pqad->bee_data) {
     1101                        query_del(local_bee->ui_data, pqad->bee_data);
     1102                }
     1103                g_free(pqad);
     1104                break;
     1105        case PURPLE_REQUEST_INPUT:
     1106                ri = data;
     1107                pd = ri->ic->proto_data;
     1108                imcb_remove_buddy(ri->ic, ri->buddy, NULL);
     1109                g_free(ri->buddy);
     1110                g_hash_table_remove(pd->input_requests, GUINT_TO_POINTER(ri->id));
     1111                break;
     1112        default:
     1113                g_free(data);
     1114                break;
     1115        }
     1116
     1117}
    10901118
    10911119void* prplcb_request_input(const char *title, const char *primary,
     
    10991127        struct request_input_data *ri = g_new0(struct request_input_data, 1);
    11001128        guint id = pd->next_request_id++;
    1101         gchar *buddy = g_strdup_printf("%s_%u", PURPLE_REQUEST_HANDLE, id);
    1102 
     1129
     1130        ri->id = id;
     1131        ri->ic = ic;
     1132        ri->buddy = g_strdup_printf("%s_%u", PURPLE_REQUEST_HANDLE, id);
    11031133        ri->data_callback = (ri_callback_t) ok_cb;
    11041134        ri->user_data = user_data;
    11051135        g_hash_table_insert(pd->input_requests, GUINT_TO_POINTER(id), ri);
    11061136
    1107         imcb_add_buddy(ic, buddy, NULL);
    1108         imcb_buddy_msg(ic, buddy, secondary, 0, 0);
    1109 
    1110         g_free(buddy);
    1111         return 0;
     1137        imcb_add_buddy(ic, ri->buddy, NULL);
     1138        imcb_buddy_msg(ic, ri->buddy, secondary, 0, 0);
     1139
     1140        return ri;
    11121141}
    11131142
     
    11161145{
    11171146        struct purple_data *pd = ic->proto_data;
    1118         struct request_input_data *ri = g_hash_table_lookup(pd->input_requests,
    1119                                                             GUINT_TO_POINTER(id));
    1120 
    1121         if (ri) {
    1122                 ri->data_callback(ri->user_data, message);
    1123         }
    1124 
    1125         imcb_remove_buddy(ic, who, NULL);
    1126         g_hash_table_remove(pd->input_requests, GUINT_TO_POINTER(id));
     1147        struct request_input_data *ri;
     1148
     1149        if (!(ri = g_hash_table_lookup(pd->input_requests, GUINT_TO_POINTER(id)))) {
     1150                return;
     1151        }
     1152
     1153        ri->data_callback(ri->user_data, message);
     1154
     1155        purple_request_close(PURPLE_REQUEST_INPUT, ri);
    11271156}
    11281157
Note: See TracChangeset for help on using the changeset viewer.