Mercurial > pidgin
comparison src/protocols/toc/toc.c @ 6306:69c9b6e63a98
[gaim-migrate @ 6805]
This fixes a crash sending toc messages with certain characters. I
broke it in the great constification of 0.64cvs.
http://sourceforge.net/tracker/?group_id=235&atid=100235&func=detail&aid=775318
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Sat, 26 Jul 2003 15:57:07 +0000 |
| parents | 11bedb793a44 |
| children | 3613007cbb6e |
comparison
equal
deleted
inserted
replaced
| 6305:1fbdca69a25e | 6306:69c9b6e63a98 |
|---|---|
| 286 pos += g_snprintf(&s[pos], len - pos, "d %s\n", (char *)dlist->data); | 286 pos += g_snprintf(&s[pos], len - pos, "d %s\n", (char *)dlist->data); |
| 287 dlist = dlist->next; | 287 dlist = dlist->next; |
| 288 } | 288 } |
| 289 } | 289 } |
| 290 | 290 |
| 291 static int escape_message(char *msg) | 291 char *escape_message(const char *msg) |
| 292 { | 292 { |
| 293 char *c, *cpy; | 293 char *ret; |
| 294 int cnt = 0; | 294 int i, j; |
| 295 /* Assumes you have a buffer able to cary at least BUF_LEN * 2 bytes */ | 295 |
| 296 if (strlen(msg) > BUF_LEN) { | 296 if (!msg) |
| 297 debug_printf("Warning: truncating message to 2048 bytes\n"); | 297 return NULL; |
| 298 msg[2047] = '\0'; | 298 |
| 299 } | 299 /* Calculate the length after escaping */ |
| 300 | 300 for (i=0, j=0; msg[i]; i++) |
| 301 cpy = g_strdup(msg); | 301 switch (msg[i]) { |
| 302 c = cpy; | 302 case '$': |
| 303 while (*c) { | 303 case '[': |
| 304 switch (*c) { | 304 case ']': |
| 305 case '$': | 305 case '(': |
| 306 case '[': | 306 case ')': |
| 307 case ']': | 307 j++; |
| 308 case '(': | 308 default: |
| 309 case ')': | 309 j++; |
| 310 msg[cnt++] = '\\'; | |
| 311 /* Fall through */ | |
| 312 default: | |
| 313 msg[cnt++] = *c; | |
| 314 } | 310 } |
| 315 c++; | 311 |
| 316 } | 312 /* Allocate a string */ |
| 317 msg[cnt] = '\0'; | 313 ret = (char *)malloc((j+1) * sizeof(char)); |
| 318 g_free(cpy); | 314 |
| 319 return cnt; | 315 /* Copy the string */ |
| 316 for (i=0, j=0; msg[i]; i++) | |
| 317 switch (msg[i]) { | |
| 318 case '$': | |
| 319 case '[': | |
| 320 case ']': | |
| 321 case '(': | |
| 322 case ')': | |
| 323 ret[j++] = '\\'; | |
| 324 default: | |
| 325 ret[j++] = msg[i]; | |
| 326 } | |
| 327 ret[j] = '\0'; | |
| 328 | |
| 329 return ret; | |
| 320 } | 330 } |
| 321 | 331 |
| 322 /* | 332 /* |
| 323 * Duplicates the input string, replacing each \n with a <BR>, and | 333 * Duplicates the input string, replacing each \n with a <BR>, and |
| 324 * escaping a few other characters. | 334 * escaping a few other characters. |
| 330 | 340 |
| 331 if (!msg) | 341 if (!msg) |
| 332 return NULL; | 342 return NULL; |
| 333 | 343 |
| 334 /* Calculate the length after escaping */ | 344 /* Calculate the length after escaping */ |
| 335 i = 0; | 345 for (i=0, j=0; msg[i]; i++) |
| 336 j = 0; | |
| 337 while (msg[i++]) | |
| 338 switch (msg[i]) { | 346 switch (msg[i]) { |
| 339 case '\n': | 347 case '\n': |
| 340 j += 4; | 348 j += 4; |
| 341 break; | 349 break; |
| 342 case '{': | 350 case '{': |
| 343 case '}': | 351 case '}': |
| 344 case '\\': | 352 case '\\': |
| 345 case '"': | 353 case '"': |
| 346 j += 1; | 354 j += 1; |
| 347 default: | 355 default: |
| 348 j += 1; | 356 j += 1; |
| 349 } | 357 } |
| 350 | 358 |
| 351 /* Allocate a string */ | 359 /* Allocate a string */ |
| 352 ret = (char *)malloc((j+1) * sizeof(char)); | 360 ret = (char *)malloc((j+1) * sizeof(char)); |
| 353 | 361 |
| 354 /* Copy the string */ | 362 /* Copy the string */ |
| 355 i = 0; | 363 for (i=0, j=0; msg[i]; i++) |
| 356 j = 0; | |
| 357 while (msg[i]) { | |
| 358 switch (msg[i]) { | 364 switch (msg[i]) { |
| 359 case '\n': | 365 case '\n': |
| 360 ret[j] = '<'; | 366 ret[j++] = '<'; |
| 361 ret[j+1] = 'B'; | 367 ret[j++] = 'B'; |
| 362 ret[j+2] = 'R'; | 368 ret[j++] = 'R'; |
| 363 ret[j+3] = '>'; | 369 ret[j++] = '>'; |
| 364 j += 4; | 370 break; |
| 365 break; | 371 case '{': |
| 366 case '{': | 372 case '}': |
| 367 case '}': | 373 case '\\': |
| 368 case '\\': | 374 case '"': |
| 369 case '"': | 375 ret[j++] = '\\'; |
| 370 ret[j] = '\\'; | 376 default: |
| 371 j++; | 377 ret[j++] = msg[i]; |
| 372 default: | |
| 373 ret[j] = msg[i]; | |
| 374 j++; | |
| 375 } | 378 } |
| 376 i++; | |
| 377 } | |
| 378 ret[j] = '\0'; | 379 ret[j] = '\0'; |
| 379 | 380 |
| 380 return ret; | 381 return ret; |
| 381 } | 382 } |
| 382 | 383 |
| 383 static int sflap_send(GaimConnection *gc, char *buf, int olen, int type) | 384 static int sflap_send(GaimConnection *gc, const char *buf, int olen, int type) |
| 384 { | 385 { |
| 386 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | |
| 385 int len; | 387 int len; |
| 386 int slen = 0; | 388 int slen = 0; |
| 389 int ret; | |
| 387 struct sflap_hdr hdr; | 390 struct sflap_hdr hdr; |
| 388 char obuf[MSG_LEN]; | 391 char *escaped, *obuf; |
| 389 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | |
| 390 | 392 |
| 391 if (tdt->state == STATE_PAUSE) | 393 if (tdt->state == STATE_PAUSE) |
| 392 /* TOC has given us the PAUSE message; sending could cause a disconnect | 394 /* TOC has given us the PAUSE message; sending could cause a disconnect |
| 393 * so we just return here like everything went through fine */ | 395 * so we just return here like everything went through fine */ |
| 394 return 0; | 396 return 0; |
| 395 | 397 |
| 396 if (olen < 0) | 398 if (olen < 0) { |
| 397 len = escape_message(buf); | 399 escaped = escape_message(buf); |
| 398 else | 400 len = strlen(buf); |
| 401 } else { | |
| 402 escaped = g_memdup(buf, olen); | |
| 399 len = olen; | 403 len = olen; |
| 400 | 404 } |
| 401 /* One _last_ 2048 check here! This shouldn't ever | 405 |
| 402 * get hit though, hopefully. If it gets hit on an IM | 406 /* |
| 403 * It'll lose the last " and the message won't go through, | 407 * One _last_ 2048 check here! This shouldn't ever |
| 404 * but this'll stop a segfault. */ | 408 * get hit though, hopefully. If it gets hit on an IM |
| 409 * It'll lose the last " and the message won't go through, | |
| 410 * but this'll stop a segfault. | |
| 411 */ | |
| 405 if (len > MSG_LEN) { | 412 if (len > MSG_LEN) { |
| 406 debug_printf("message too long, truncating\n"); | 413 debug_printf("message too long, truncating\n"); |
| 407 buf[MSG_LEN - 1] = '\0'; | 414 escaped[MSG_LEN - 1] = '\0'; |
| 408 len = MSG_LEN; | 415 len = MSG_LEN; |
| 409 } | 416 } |
| 410 | 417 |
| 411 if (olen < 0) | 418 if (olen < 0) |
| 412 debug_printf("TOC C: %s\n", buf); | 419 debug_printf("TOC C: %s\n", escaped); |
| 413 | 420 |
| 414 hdr.ast = '*'; | 421 hdr.ast = '*'; |
| 415 hdr.type = type; | 422 hdr.type = type; |
| 416 hdr.seqno = htons(tdt->seqno++ & 0xffff); | 423 hdr.seqno = htons(tdt->seqno++ & 0xffff); |
| 417 hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1)); | 424 hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1)); |
| 418 | 425 |
| 426 obuf = (char *)malloc((sizeof(hdr)+len+1) * sizeof(char)); | |
| 419 memcpy(obuf, &hdr, sizeof(hdr)); | 427 memcpy(obuf, &hdr, sizeof(hdr)); |
| 420 slen += sizeof(hdr); | 428 slen += sizeof(hdr); |
| 421 memcpy(&obuf[slen], buf, len); | 429 |
| 430 memcpy(&obuf[slen], escaped, len); | |
| 422 slen += len; | 431 slen += len; |
| 432 | |
| 423 if (type != TYPE_SIGNON) { | 433 if (type != TYPE_SIGNON) { |
| 424 obuf[slen] = '\0'; | 434 obuf[slen] = '\0'; |
| 425 slen += 1; | 435 slen += 1; |
| 426 } | 436 } |
| 427 | 437 |
| 428 return toc_write(tdt->toc_fd, obuf, slen); | 438 ret = toc_write(tdt->toc_fd, obuf, slen); |
| 439 free(obuf); | |
| 440 free(escaped); | |
| 441 | |
| 442 return ret; | |
| 429 } | 443 } |
| 430 | 444 |
| 431 static int wait_reply(GaimConnection *gc, char *buffer, size_t buflen) | 445 static int wait_reply(GaimConnection *gc, char *buffer, size_t buflen) |
| 432 { | 446 { |
| 433 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | 447 struct toc_data *tdt = (struct toc_data *)gc->proto_data; |
| 1122 | 1136 |
| 1123 static void toc_change_passwd(GaimConnection *g, const char *orig, const char *new) | 1137 static void toc_change_passwd(GaimConnection *g, const char *orig, const char *new) |
| 1124 { | 1138 { |
| 1125 char buf[BUF_LEN * 2]; | 1139 char buf[BUF_LEN * 2]; |
| 1126 g_snprintf(buf, BUF_LONG, "toc_change_passwd %s %s", orig, new); | 1140 g_snprintf(buf, BUF_LONG, "toc_change_passwd %s %s", orig, new); |
| 1127 sflap_send(g, buf, strlen(buf), TYPE_DATA); | 1141 sflap_send(g, buf, -1, TYPE_DATA); |
| 1128 } | 1142 } |
| 1129 | 1143 |
| 1130 static void toc_add_buddy(GaimConnection *g, const char *name) | 1144 static void toc_add_buddy(GaimConnection *g, const char *name) |
| 1131 { | 1145 { |
| 1132 char buf[BUF_LEN * 2]; | 1146 char buf[BUF_LEN * 2]; |
