Mercurial > pidgin.yaz
comparison libpurple/util.c @ 29693:7925bb7f2aa7
propagate from branch 'im.pidgin.pidgin' (head 92e101e3698042e7600729bc09dec9e28f81de8f)
to branch 'im.pidgin.cpw.attention_ui' (head 563c35d20efcc234a74567ebb88c059d10ce1e09)
author | Marcus Lundblad <ml@update.uu.se> |
---|---|
date | Mon, 24 Aug 2009 19:23:56 +0000 |
parents | 703b20fa6c5c |
children | 63d8b9b93cba c9c038529f38 39716f7d2c93 |
comparison
equal
deleted
inserted
replaced
29692:fb99a0067812 | 29693:7925bb7f2aa7 |
---|---|
403 state_encoded_text, state_question4, state_equal2 = state_start | 403 state_encoded_text, state_question4, state_equal2 = state_start |
404 } encoded_word_state_t; | 404 } encoded_word_state_t; |
405 encoded_word_state_t state = state_start; | 405 encoded_word_state_t state = state_start; |
406 const char *cur, *mark; | 406 const char *cur, *mark; |
407 const char *charset0 = NULL, *encoding0 = NULL, *encoded_text0 = NULL; | 407 const char *charset0 = NULL, *encoding0 = NULL, *encoded_text0 = NULL; |
408 char *n, *new; | 408 GString *new; |
409 | 409 |
410 /* token can be any CHAR (supposedly ISO8859-1/ISO2022), not just ASCII */ | 410 /* token can be any CHAR (supposedly ISO8859-1/ISO2022), not just ASCII */ |
411 #define token_char_p(c) \ | 411 #define token_char_p(c) \ |
412 (c != ' ' && !iscntrl(c) && !strchr("()<>@,;:\"/[]?.=", c)) | 412 (c != ' ' && !iscntrl(c) && !strchr("()<>@,;:\"/[]?.=", c)) |
413 | 413 |
414 /* But encoded-text must be ASCII; alas, isascii() may not exist */ | 414 /* But encoded-text must be ASCII; alas, isascii() may not exist */ |
415 #define encoded_text_char_p(c) \ | 415 #define encoded_text_char_p(c) \ |
416 ((c & 0x80) == 0 && c != '?' && c != ' ' && isgraph(c)) | 416 ((c & 0x80) == 0 && c != '?' && c != ' ' && isgraph(c)) |
417 | 417 |
418 #define RECOVER_MARKED_TEXT strncpy(n, mark, cur - mark + 1); \ | |
419 n += cur - mark + 1 | |
420 | |
421 g_return_val_if_fail(str != NULL, NULL); | 418 g_return_val_if_fail(str != NULL, NULL); |
422 | 419 |
423 /* NOTE: Assuming that we need just strlen(str)+1 *may* be wrong. | 420 new = g_string_new(NULL); |
424 * It would be wrong if one byte (in some unknown encoding) could | |
425 * expand to >=4 bytes of UTF-8; I don't know if there are such things. | |
426 */ | |
427 n = new = g_malloc(strlen(str) + 1); | |
428 | 421 |
429 /* Here we will be looking for encoded words and if they seem to be | 422 /* Here we will be looking for encoded words and if they seem to be |
430 * valid then decode them. | 423 * valid then decode them. |
431 * They are of this form: =?charset?encoding?text?= | 424 * They are of this form: =?charset?encoding?text?= |
432 */ | 425 */ |
435 switch (state) { | 428 switch (state) { |
436 case state_equal1: | 429 case state_equal1: |
437 if (*cur == '?') { | 430 if (*cur == '?') { |
438 state = state_question1; | 431 state = state_question1; |
439 } else { | 432 } else { |
440 RECOVER_MARKED_TEXT; | 433 g_string_append_len(new, mark, cur - mark + 1); |
441 state = state_start; | 434 state = state_start; |
442 } | 435 } |
443 break; | 436 break; |
444 case state_question1: | 437 case state_question1: |
445 if (token_char_p(*cur)) { | 438 if (token_char_p(*cur)) { |
446 charset0 = cur; | 439 charset0 = cur; |
447 state = state_charset; | 440 state = state_charset; |
448 } else { /* This should never happen */ | 441 } else { /* This should never happen */ |
449 RECOVER_MARKED_TEXT; | 442 g_string_append_len(new, mark, cur - mark + 1); |
450 state = state_start; | 443 state = state_start; |
451 } | 444 } |
452 break; | 445 break; |
453 case state_charset: | 446 case state_charset: |
454 if (*cur == '?') { | 447 if (*cur == '?') { |
455 state = state_question2; | 448 state = state_question2; |
456 } else if (!token_char_p(*cur)) { /* This should never happen */ | 449 } else if (!token_char_p(*cur)) { /* This should never happen */ |
457 RECOVER_MARKED_TEXT; | 450 g_string_append_len(new, mark, cur - mark + 1); |
458 state = state_start; | 451 state = state_start; |
459 } | 452 } |
460 break; | 453 break; |
461 case state_question2: | 454 case state_question2: |
462 if (token_char_p(*cur)) { | 455 if (token_char_p(*cur)) { |
463 encoding0 = cur; | 456 encoding0 = cur; |
464 state = state_encoding; | 457 state = state_encoding; |
465 } else { /* This should never happen */ | 458 } else { /* This should never happen */ |
466 RECOVER_MARKED_TEXT; | 459 g_string_append_len(new, mark, cur - mark + 1); |
467 state = state_start; | 460 state = state_start; |
468 } | 461 } |
469 break; | 462 break; |
470 case state_encoding: | 463 case state_encoding: |
471 if (*cur == '?') { | 464 if (*cur == '?') { |
472 state = state_question3; | 465 state = state_question3; |
473 } else if (!token_char_p(*cur)) { /* This should never happen */ | 466 } else if (!token_char_p(*cur)) { /* This should never happen */ |
474 RECOVER_MARKED_TEXT; | 467 g_string_append_len(new, mark, cur - mark + 1); |
475 state = state_start; | 468 state = state_start; |
476 } | 469 } |
477 break; | 470 break; |
478 case state_question3: | 471 case state_question3: |
479 if (encoded_text_char_p(*cur)) { | 472 if (encoded_text_char_p(*cur)) { |
481 state = state_encoded_text; | 474 state = state_encoded_text; |
482 } else if (*cur == '?') { /* empty string */ | 475 } else if (*cur == '?') { /* empty string */ |
483 encoded_text0 = cur; | 476 encoded_text0 = cur; |
484 state = state_question4; | 477 state = state_question4; |
485 } else { /* This should never happen */ | 478 } else { /* This should never happen */ |
486 RECOVER_MARKED_TEXT; | 479 g_string_append_len(new, mark, cur - mark + 1); |
487 state = state_start; | 480 state = state_start; |
488 } | 481 } |
489 break; | 482 break; |
490 case state_encoded_text: | 483 case state_encoded_text: |
491 if (*cur == '?') { | 484 if (*cur == '?') { |
492 state = state_question4; | 485 state = state_question4; |
493 } else if (!encoded_text_char_p(*cur)) { | 486 } else if (!encoded_text_char_p(*cur)) { |
494 RECOVER_MARKED_TEXT; | 487 g_string_append_len(new, mark, cur - mark + 1); |
495 state = state_start; | 488 state = state_start; |
496 } | 489 } |
497 break; | 490 break; |
498 case state_question4: | 491 case state_question4: |
499 if (*cur == '=') { /* Got the whole encoded-word */ | 492 if (*cur == '=') { /* Got the whole encoded-word */ |
511 if (decoded) { | 504 if (decoded) { |
512 gsize len; | 505 gsize len; |
513 char *converted = g_convert((const gchar *)decoded, dec_len, "utf-8", charset, NULL, &len, NULL); | 506 char *converted = g_convert((const gchar *)decoded, dec_len, "utf-8", charset, NULL, &len, NULL); |
514 | 507 |
515 if (converted) { | 508 if (converted) { |
516 n = strncpy(n, converted, len) + len; | 509 g_string_append_len(new, converted, len); |
517 g_free(converted); | 510 g_free(converted); |
518 } | 511 } |
519 g_free(decoded); | 512 g_free(decoded); |
520 } | 513 } |
521 g_free(charset); | 514 g_free(charset); |
522 g_free(encoding); | 515 g_free(encoding); |
523 g_free(encoded_text); | 516 g_free(encoded_text); |
524 state = state_equal2; /* Restart the FSM */ | 517 state = state_equal2; /* Restart the FSM */ |
525 } else { /* This should never happen */ | 518 } else { /* This should never happen */ |
526 RECOVER_MARKED_TEXT; | 519 g_string_append_len(new, mark, cur - mark + 1); |
527 state = state_start; | 520 state = state_start; |
528 } | 521 } |
529 break; | 522 break; |
530 default: | 523 default: |
531 if (*cur == '=') { | 524 if (*cur == '=') { |
532 mark = cur; | 525 mark = cur; |
533 state = state_equal1; | 526 state = state_equal1; |
534 } else { | 527 } else { |
535 /* Some unencoded text. */ | 528 /* Some unencoded text. */ |
536 *n = *cur; | 529 g_string_append_c(new, *cur); |
537 n += 1; | |
538 } | 530 } |
539 break; | 531 break; |
540 } /* switch */ | 532 } /* switch */ |
541 } /* for */ | 533 } /* for */ |
542 | 534 |
543 if (state != state_start) { | 535 if (state != state_start) |
544 RECOVER_MARKED_TEXT; | 536 g_string_append_len(new, mark, cur - mark + 1); |
545 } | 537 |
546 *n = '\0'; | 538 return g_string_free(new, FALSE);; |
547 | |
548 return new; | |
549 } | 539 } |
550 | 540 |
551 | 541 |
552 /************************************************************************** | 542 /************************************************************************** |
553 * Date/Time Functions | 543 * Date/Time Functions |
3828 header_len = strlen(header); | 3818 header_len = strlen(header); |
3829 | 3819 |
3830 /* Note: data is _not_ nul-terminated. */ | 3820 /* Note: data is _not_ nul-terminated. */ |
3831 if (data_len > header_len) { | 3821 if (data_len > header_len) { |
3832 if (header[0] == '\n') | 3822 if (header[0] == '\n') |
3833 p = (g_strncasecmp(data, header + 1, header_len - 1) == 0) ? data : NULL; | 3823 p = (g_ascii_strncasecmp(data, header + 1, header_len - 1) == 0) ? data : NULL; |
3834 if (!p) | 3824 if (!p) |
3835 p = purple_strcasestr(data, header); | 3825 p = purple_strcasestr(data, header); |
3836 if (p) | 3826 if (p) |
3837 p += header_len; | 3827 p += header_len; |
3838 } | 3828 } |
3865 | 3855 |
3866 static gboolean | 3856 static gboolean |
3867 content_is_chunked(const char *data, size_t data_len) | 3857 content_is_chunked(const char *data, size_t data_len) |
3868 { | 3858 { |
3869 const char *p = find_header_content(data, data_len, "\nTransfer-Encoding: ", sizeof("\nTransfer-Encoding: ") - 1); | 3859 const char *p = find_header_content(data, data_len, "\nTransfer-Encoding: ", sizeof("\nTransfer-Encoding: ") - 1); |
3870 if (p && g_strncasecmp(p, "chunked", 7) == 0) | 3860 if (p && g_ascii_strncasecmp(p, "chunked", 7) == 0) |
3871 return TRUE; | 3861 return TRUE; |
3872 | 3862 |
3873 return FALSE; | 3863 return FALSE; |
3874 } | 3864 } |
3875 | 3865 |