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