comparison libpurple/protocols/yahoo/yahoo_aliases.c @ 23007:318905da6f8d

Fix a printf("%s", NULL) situation and plug some leakage. Fixes #5280.
author Daniel Atallah <daniel.atallah@gmail.com>
date Tue, 20 May 2008 02:14:50 +0000
parents 0b11895cc564
children adbcf5b84438
comparison
equal deleted inserted replaced
23006:d3aace801919 23007:318905da6f8d
46 /** 46 /**
47 * Stuff we want passed to the callback function 47 * Stuff we want passed to the callback function
48 */ 48 */
49 struct callback_data { 49 struct callback_data {
50 PurpleConnection *gc; 50 PurpleConnection *gc;
51 char *id; 51 gchar *id;
52 }; 52 };
53 53
54 54
55 /************************************************************************** 55 /**************************************************************************
56 * Alias Fetch Functions 56 * Alias Fetch Functions
57 **************************************************************************/ 57 **************************************************************************/
58 58
59 static void 59 static void
60 yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,const gchar *url_text, size_t len, const gchar *error_message) 60 yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
61 { 61 {
62 struct callback_data *cb = user_data; 62 struct callback_data *cb = user_data;
63 PurpleConnection *gc = cb->gc; 63 PurpleConnection *gc = cb->gc;
64 struct yahoo_data *yd = gc->proto_data; 64 struct yahoo_data *yd = gc->proto_data;
65 65
67 67
68 if (len == 0) { 68 if (len == 0) {
69 purple_debug_info("yahoo", "No Aliases to process.%s%s\n", 69 purple_debug_info("yahoo", "No Aliases to process.%s%s\n",
70 error_message ? " Error:" : "", error_message ? error_message : ""); 70 error_message ? " Error:" : "", error_message ? error_message : "");
71 } else { 71 } else {
72 gchar *full_name, *nick_name, *alias; 72 gchar *full_name, *nick_name;
73 const char *yid, *id, *fn, *ln, *nn; 73 const char *yid, *id, *fn, *ln, *nn, *alias;
74 YahooFriend *f; 74 YahooFriend *f;
75 PurpleBuddy *b; 75 PurpleBuddy *b;
76 xmlnode *item, *contacts; 76 xmlnode *item, *contacts;
77 77
78 /* Put our web response into a xmlnode for easy management */ 78 /* Put our web response into a xmlnode for easy management */
79 contacts = xmlnode_from_str(url_text, -1); 79 contacts = xmlnode_from_str(url_text, -1);
80 80
81 if (contacts == NULL) { 81 if (contacts == NULL) {
82 purple_debug_error("yahoo_aliases","Badly formed XML\n"); 82 purple_debug_error("yahoo", "Badly formed Alias XML\n");
83 g_free(cb->id);
84 g_free(cb);
83 return; 85 return;
84 } 86 }
85 purple_debug_info("yahoo", "Fetched %" G_GSIZE_FORMAT 87 purple_debug_info("yahoo", "Fetched %" G_GSIZE_FORMAT
86 " bytes of alias data\n", len); 88 " bytes of alias data\n", len);
87 89
88 /* Loop around and around and around until we have gone through all the received aliases */ 90 /* Loop around and around and around until we have gone through all the received aliases */
89 for(item = xmlnode_get_child(contacts, "ct"); item; item = xmlnode_get_next_twin(item)) { 91 for(item = xmlnode_get_child(contacts, "ct"); item; item = xmlnode_get_next_twin(item)) {
90 /* Yahoo replies with two types of contact (ct) record, we are only interested in the alias ones */ 92 /* Yahoo replies with two types of contact (ct) record, we are only interested in the alias ones */
91 if ((yid = xmlnode_get_attrib(item, "yi"))) { 93 if ((yid = xmlnode_get_attrib(item, "yi"))) {
92 /* Grab all the bits of information we can */ 94 /* Grab all the bits of information we can */
93 fn = xmlnode_get_attrib(item,"fn"); 95 fn = xmlnode_get_attrib(item, "fn");
94 ln = xmlnode_get_attrib(item,"ln"); 96 ln = xmlnode_get_attrib(item, "ln");
95 nn = xmlnode_get_attrib(item,"nn"); 97 nn = xmlnode_get_attrib(item, "nn");
96 id = xmlnode_get_attrib(item,"id"); 98 id = xmlnode_get_attrib(item, "id");
97 99
98 full_name = nick_name = alias = NULL; 100 full_name = nick_name = NULL;
101 alias = NULL;
99 102
100 /* Yahoo stores first and last names separately, lets put them together into a full name */ 103 /* Yahoo stores first and last names separately, lets put them together into a full name */
101 if (yd->jp) 104 if (yd->jp)
102 full_name = g_strstrip(g_strdup_printf("%s %s", (ln != NULL ? ln : "") , (fn != NULL ? fn : ""))); 105 full_name = g_strstrip(g_strdup_printf("%s %s", (ln != NULL ? ln : "") , (fn != NULL ? fn : "")));
103 else 106 else
104 full_name = g_strstrip(g_strdup_printf("%s %s", (fn != NULL ? fn : "") , (ln != NULL ? ln : ""))); 107 full_name = g_strstrip(g_strdup_printf("%s %s", (fn != NULL ? fn : "") , (ln != NULL ? ln : "")));
105 nick_name = (nn != NULL ? g_strstrip(g_strdup_printf("%s", nn)) : NULL); 108 nick_name = (nn != NULL ? g_strstrip(g_strdup(nn)) : NULL);
106 109
107 if (nick_name != NULL) 110 if (nick_name != NULL)
108 alias = nick_name; /* If we have a nickname from Yahoo, let's use it */ 111 alias = nick_name; /* If we have a nickname from Yahoo, let's use it */
109 else if (strlen(full_name) != 0) 112 else if (strlen(full_name) != 0)
110 alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */ 113 alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */
113 f = yahoo_friend_find(cb->gc, yid); 116 f = yahoo_friend_find(cb->gc, yid);
114 b = purple_find_buddy(cb->gc->account, yid); 117 b = purple_find_buddy(cb->gc->account, yid);
115 118
116 /* If we don't find a matching buddy, ignore the alias !! */ 119 /* If we don't find a matching buddy, ignore the alias !! */
117 if (f != NULL && b != NULL) { 120 if (f != NULL && b != NULL) {
121 const char *buddy_alias = purple_buddy_get_alias(b);
118 yahoo_friend_set_alias_id(f, id); 122 yahoo_friend_set_alias_id(f, id);
119 123
120 /* Finally, if we received an alias, we better update the buddy list */ 124 /* Finally, if we received an alias, we better update the buddy list */
121 if (alias != NULL) { 125 if (alias != NULL) {
122 serv_got_alias(cb->gc, yid, alias); 126 serv_got_alias(cb->gc, yid, alias);
123 purple_debug_info("yahoo","Fetched alias '%s' (%s)\n",alias,id); 127 purple_debug_info("yahoo", "Fetched alias '%s' (%s)\n", alias, id);
124 } else if (b->alias != alias && strcmp(b->alias, "") != 0) { 128 } else if (buddy_alias != NULL && strcmp(buddy_alias, "") != 0) {
125 /* Or if we have an alias that Yahoo doesn't, send it up */ 129 /* Or if we have an alias that Yahoo doesn't, send it up */
126 yahoo_update_alias(cb->gc, yid, b->alias); 130 yahoo_update_alias(cb->gc, yid, buddy_alias);
127 purple_debug_info("yahoo","Sent alias '%s'\n", b->alias); 131 purple_debug_info("yahoo", "Sent updated alias '%s'\n", buddy_alias);
128 } 132 }
129 } else { 133 } else {
130 purple_debug_info("yahoo", "Bizarre, received alias for %s, but they are not on your list...\n", yid); 134 purple_debug_info("yahoo", "Bizarre, received alias for %s, but they are not on your list...\n", yid);
131 } 135 }
132 136
134 g_free(nick_name); 138 g_free(nick_name);
135 } 139 }
136 } 140 }
137 xmlnode_free(contacts); 141 xmlnode_free(contacts);
138 } 142 }
143
139 g_free(cb->id); 144 g_free(cb->id);
140 g_free(cb); 145 g_free(cb);
141 } 146 }
142 147
143 void 148 void
144 yahoo_fetch_aliases(PurpleConnection *gc) 149 yahoo_fetch_aliases(PurpleConnection *gc)
145 { 150 {
146 struct yahoo_data *yd = gc->proto_data; 151 struct yahoo_data *yd = gc->proto_data;
147 struct callback_data *cb; 152 struct callback_data *cb;
148 const char *url; 153 const char *url;
149 char *request, *webpage, *webaddress; 154 gchar *request, *webpage, *webaddress;
150 PurpleUtilFetchUrlData *url_data; 155 PurpleUtilFetchUrlData *url_data;
151 156
152 gboolean use_whole_url = FALSE; 157 gboolean use_whole_url = FALSE;
153 158
154 /* use whole URL if using HTTP Proxy */ 159 /* use whole URL if using HTTP Proxy */
155 if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP)) 160 if ((gc->account->proxy_info)
156 use_whole_url = TRUE; 161 && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP))
162 use_whole_url = TRUE;
157 163
158 /* Using callback_data so I have access to gc in the callback function */ 164 /* Using callback_data so I have access to gc in the callback function */
159 cb = g_new0(struct callback_data, 1); 165 cb = g_new0(struct callback_data, 1);
160 cb->gc = gc; 166 cb->gc = gc;
161 167
165 request = g_strdup_printf("GET %s%s/%s HTTP/1.1\r\n" 171 request = g_strdup_printf("GET %s%s/%s HTTP/1.1\r\n"
166 "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" 172 "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n"
167 "Cookie: T=%s; Y=%s\r\n" 173 "Cookie: T=%s; Y=%s\r\n"
168 "Host: %s\r\n" 174 "Host: %s\r\n"
169 "Cache-Control: no-cache\r\n\r\n", 175 "Cache-Control: no-cache\r\n\r\n",
170 use_whole_url ? "http://" : "", use_whole_url ? webaddress : "", webpage, yd->cookie_t,yd->cookie_y, webaddress); 176 use_whole_url ? "http://" : "", use_whole_url ? webaddress : "", webpage,
177 yd->cookie_t, yd->cookie_y,
178 webaddress);
171 179
172 /* We have a URL and some header information, let's connect and get some aliases */ 180 /* We have a URL and some header information, let's connect and get some aliases */
173 url_data = purple_util_fetch_url_request(url, use_whole_url, NULL, TRUE, request, FALSE, yahoo_fetch_aliases_cb, cb); 181 url_data = purple_util_fetch_url_request(url, use_whole_url, NULL, TRUE,
174 if (url_data != NULL) { 182 request, FALSE,
183 yahoo_fetch_aliases_cb, cb);
184 if (url_data != NULL)
175 yd->url_datas = g_slist_prepend(yd->url_datas, url_data); 185 yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
176 }
177 186
178 g_free(webaddress); 187 g_free(webaddress);
179 g_free(webpage); 188 g_free(webpage);
180 g_free(request); 189 g_free(request);
181 } 190 }
183 /************************************************************************** 192 /**************************************************************************
184 * Alias Update Functions 193 * Alias Update Functions
185 **************************************************************************/ 194 **************************************************************************/
186 195
187 static void 196 static void
188 yahoo_update_alias_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,const gchar *url_text, size_t len, const gchar *error_message) 197 yahoo_update_alias_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
189 { 198 {
190 xmlnode *node, *result; 199 xmlnode *node, *result;
191 struct callback_data *cb = user_data; 200 struct callback_data *cb = user_data;
192 PurpleConnection *gc = cb->gc; 201 PurpleConnection *gc = cb->gc;
193 struct yahoo_data *yd; 202 struct yahoo_data *yd;
203 return; 212 return;
204 } 213 }
205 214
206 result = xmlnode_from_str(url_text, -1); 215 result = xmlnode_from_str(url_text, -1);
207 216
208 purple_debug_info("yahoo", "ID: %s, Return data: %s\n",cb->id, url_text); 217 purple_debug_info("yahoo", "ID: %s, Return data: %s\n", cb->id, url_text);
209 218
210 if (result == NULL) { 219 if (result == NULL) {
211 purple_debug_error("yahoo","Alias update failed: Badly formed response\n"); 220 purple_debug_error("yahoo", "Alias update failed: Badly formed response\n");
212 g_free(cb->id); 221 g_free(cb->id);
213 g_free(cb); 222 g_free(cb);
214 return; 223 return;
215 } 224 }
216 225
217 if ((node = xmlnode_get_child(result, "ct"))) { 226 if ((node = xmlnode_get_child(result, "ct"))) {
218 if (g_ascii_strncasecmp(xmlnode_get_attrib(node, "id"), cb->id, strlen(cb->id))==0) 227 const char *update_id = xmlnode_get_attrib(node, "id");
228 if (g_ascii_strncasecmp(update_id, cb->id, strlen(cb->id)) == 0)
219 purple_debug_info("yahoo", "Alias update succeeded\n"); 229 purple_debug_info("yahoo", "Alias update succeeded\n");
220 else 230 else
221 purple_debug_error("yahoo", "Alias update failed (Contact record return mismatch)\n"); 231 purple_debug_error("yahoo", "Alias update failed (Contact record return mismatch)\n");
222 } else { 232 } else {
223 purple_debug_info("yahoo", "Alias update failed (No contact record returned)\n"); 233 purple_debug_info("yahoo", "Alias update failed (No contact record returned)\n");
230 240
231 void 241 void
232 yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias) 242 yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
233 { 243 {
234 struct yahoo_data *yd; 244 struct yahoo_data *yd;
235 char *content, *url, *request, *webpage, *webaddress, *strtmp; 245 const char *url, *alias_id;
236 char *escaped_alias, *alias_jp, *converted_alias_jp; 246 gchar *content, *request, *webpage, *webaddress;
237 int inttmp;
238 struct callback_data *cb; 247 struct callback_data *cb;
239 PurpleUtilFetchUrlData *url_data; 248 PurpleUtilFetchUrlData *url_data;
240 gboolean use_whole_url = FALSE; 249 gboolean use_whole_url = FALSE;
241 YahooFriend *f; 250 YahooFriend *f;
242 251
243 /* use whole URL if using HTTP Proxy */ 252 /* use whole URL if using HTTP Proxy */
244 if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP)) 253 if ((gc->account->proxy_info)
245 use_whole_url = TRUE; 254 && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP))
246 255 use_whole_url = TRUE;
247 g_return_if_fail(alias != NULL); 256
248 g_return_if_fail(who != NULL); 257 g_return_if_fail(who != NULL);
249 g_return_if_fail(gc != NULL); 258 g_return_if_fail(gc != NULL);
250 259
260 if (alias == NULL)
261 alias = "";
262
251 purple_debug_info("yahoo", "Sending '%s' as new alias for user '%s'.\n", alias, who); 263 purple_debug_info("yahoo", "Sending '%s' as new alias for user '%s'.\n", alias, who);
252 264
253 f = yahoo_friend_find(gc, who); 265 f = yahoo_friend_find(gc, who);
254 if (f == NULL) { 266 if (f == NULL) {
255 purple_debug_info("yahoo", "Missing proto_data (get_yahoo_aliases must have failed), bailing out\n"); 267 purple_debug_error("yahoo", "Missing YahooFriend. Unable to set server alias.\n");
268 return;
269 }
270
271 alias_id = yahoo_friend_get_alias_id(f);
272 if (alias_id == NULL) {
273 purple_debug_error("yahoo", "Missing Yahoo Alias ID (get_yahoo_aliases must have failed), bailing out\n");
256 return; 274 return;
257 } 275 }
258 276
259 yd = gc->proto_data; 277 yd = gc->proto_data;
260 278
261 /* Using callback_data so I have access to gc in the callback function */ 279 /* Using callback_data so I have access to gc in the callback function */
262 cb = g_new0(struct callback_data, 1); 280 cb = g_new0(struct callback_data, 1);
263 cb->id = g_strdup(yahoo_friend_get_alias_id(f)); 281 cb->id = g_strdup(alias_id);
264 cb->gc = gc; 282 cb->gc = gc;
265 283
266 /* Build all the info to make the web request */ 284 /* Build all the info to make the web request */
267 url = yd->jp? YAHOOJP_ALIAS_UPDATE_URL: YAHOO_ALIAS_UPDATE_URL; 285 url = yd->jp ? YAHOOJP_ALIAS_UPDATE_URL: YAHOO_ALIAS_UPDATE_URL;
268 purple_url_parse(url, &webaddress, &inttmp, &webpage, &strtmp, &strtmp); 286 purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL);
269 287
270 if (yd->jp) { 288 if (yd->jp) {
271 alias_jp = g_convert(alias, strlen(alias), "EUC-JP", "UTF-8", NULL, NULL, NULL); 289 gchar *alias_jp = g_convert(alias, -1, "EUC-JP", "UTF-8", NULL, NULL, NULL);
272 converted_alias_jp = yahoo_convert_to_numeric(alias_jp); 290 gchar *converted_alias_jp = yahoo_convert_to_numeric(alias_jp);
273 content = g_strdup_printf("<ab k=\"%s\" cc=\"1\">\n" 291 content = g_strdup_printf("<ab k=\"%s\" cc=\"1\">\n"
274 "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n", 292 "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n",
275 gc->account->username, who, yahoo_friend_get_alias_id(f), converted_alias_jp); 293 purple_account_get_username(gc->account),
294 who, alias_id, converted_alias_jp);
276 free(converted_alias_jp); 295 free(converted_alias_jp);
277 g_free(alias_jp); 296 g_free(alias_jp);
278 } 297 } else {
279 else { 298 gchar *escaped_alias = g_markup_escape_text(alias, -1);
280 escaped_alias = g_markup_escape_text(alias, strlen(alias));
281 content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"1\">\n" 299 content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"1\">\n"
282 "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n", 300 "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n",
283 gc->account->username, who, yahoo_friend_get_alias_id(f), escaped_alias); 301 purple_account_get_username(gc->account),
302 who, alias_id, escaped_alias);
284 g_free(escaped_alias); 303 g_free(escaped_alias);
285 } 304 }
286 305
287 request = g_strdup_printf("POST %s%s/%s HTTP/1.1\r\n" 306 request = g_strdup_printf("POST %s%s/%s HTTP/1.1\r\n"
288 "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" 307 "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n"
289 "Cookie: T=%s; Y=%s\r\n" 308 "Cookie: T=%s; Y=%s\r\n"
290 "Host: %s\r\n" 309 "Host: %s\r\n"
291 "Content-Length: %" G_GSIZE_FORMAT "\r\n" 310 "Content-Length: %" G_GSIZE_FORMAT "\r\n"
292 "Cache-Control: no-cache\r\n\r\n" 311 "Cache-Control: no-cache\r\n\r\n"
293 "%s", 312 "%s",
294 use_whole_url ? "http://" : "", use_whole_url ? webaddress : "", webpage, yd->cookie_t,yd->cookie_y, webaddress, 313 use_whole_url ? "http://" : "", use_whole_url ? webaddress : "", webpage,
295 strlen(content), content); 314 yd->cookie_t, yd->cookie_y,
315 webaddress,
316 strlen(content),
317 content);
296 318
297 /* We have a URL and some header information, let's connect and update the alias */ 319 /* We have a URL and some header information, let's connect and update the alias */
298 url_data = purple_util_fetch_url_request(url, use_whole_url, NULL, TRUE, request, FALSE, yahoo_update_alias_cb, cb); 320 url_data = purple_util_fetch_url_request(url, use_whole_url, NULL, TRUE, request, FALSE, yahoo_update_alias_cb, cb);
299 if (url_data != NULL) { 321 if (url_data != NULL)
300 yd->url_datas = g_slist_prepend(yd->url_datas, url_data); 322 yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
301 } 323
302 324 g_free(webpage);
325 g_free(webaddress);
303 g_free(content); 326 g_free(content);
304 g_free(request); 327 g_free(request);
305 } 328 }
306 329