diff options
Diffstat (limited to 'camel/camel-mime-utils.c')
-rw-r--r-- | camel/camel-mime-utils.c | 177 |
1 files changed, 93 insertions, 84 deletions
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c index 6ba498ffa9..257c1574fc 100644 --- a/camel/camel-mime-utils.c +++ b/camel/camel-mime-utils.c @@ -39,6 +39,8 @@ #define MAXHOSTNAMELEN 1024 #endif +#include <iconv.h> + #include <time.h> #include <ctype.h> @@ -46,8 +48,9 @@ #include <regex.h> #include <glib.h> +#include <gal/unicode/gunicode.h> #include <gal/util/e-iconv.h> -#include <e-util/e-time-utils.h> +#include "e-time-utils.h" #include "camel-mime-utils.h" #include "camel-charset-map.h" @@ -1011,7 +1014,7 @@ rfc2047_decode_word(const char *in, size_t len) d(printf("found ?, encoding is '%c'\n", inptr[0])); inptr++; tmplen = inend-inptr-2; - decword = g_alloca (tmplen); /* this will always be more-than-enough room */ + decword = alloca(tmplen); /* this will always be more-than-enough room */ switch(toupper(inptr[0])) { case 'Q': inlen = quoted_decode(inptr+2, tmplen, decword); @@ -1032,7 +1035,7 @@ rfc2047_decode_word(const char *in, size_t len) if (inlen > 0) { /* yuck, all this snot is to setup iconv! */ tmplen = inptr - in - 3; - encname = g_alloca (tmplen + 1); + encname = alloca (tmplen + 1); memcpy (encname, in + 2, tmplen); encname[tmplen] = '\0'; @@ -1053,7 +1056,7 @@ rfc2047_decode_word(const char *in, size_t len) inbuf = decword; outlen = inlen * 6 + 16; - outbase = g_alloca (outlen); + outbase = alloca (outlen); outbuf = outbase; retry: @@ -1068,7 +1071,7 @@ rfc2047_decode_word(const char *in, size_t len) e_iconv_close (ic); } else { w(g_warning ("Cannot decode charset, header display may be corrupt: %s: %s", - charset, strerror (errno))); + charset, g_strerror (errno))); if (!retried) { charset = e_iconv_locale_charset (); @@ -1090,6 +1093,18 @@ rfc2047_decode_word(const char *in, size_t len) return decoded; } +/* grrr, glib should have this ! */ +static GString * +g_string_append_len(GString *st, const char *s, size_t l) +{ + char *tmp; + + tmp = alloca(l+1); + tmp[l]=0; + memcpy(tmp, s, l); + return g_string_append(st, tmp); +} + /* ok, a lot of mailers are BROKEN, and send iso-latin1 encoded headers, when they should just be sticking to US-ASCII according to the rfc's. Anyway, since the conversion to utf-8 @@ -1126,17 +1141,17 @@ append_8bit (GString *out, const char *inbuf, size_t inlen, const char *charset) outlen = inlen * 6 + 16; outbuf = outbase = g_malloc(outlen); - if (e_iconv (ic, &inbuf, &inlen, &outbuf, &outlen) == (size_t) -1) { - w(g_warning("Conversion to '%s' failed: %s", charset, strerror (errno))); + if (e_iconv(ic, &inbuf, &inlen, &outbuf, &outlen) == (size_t) -1) { + w(g_warning("Conversion to '%s' failed: %s", charset, strerror(errno))); g_free(outbase); - e_iconv_close (ic); + e_iconv_close(ic); return FALSE; } *outbuf = 0; g_string_append(out, outbase); g_free(outbase); - e_iconv_close (ic); + e_iconv_close(ic); return TRUE; @@ -1149,10 +1164,10 @@ header_decode_text (const char *in, size_t inlen, const char *default_charset) GString *out; const char *inptr, *inend, *start, *chunk, *locale_charset; char *dword = NULL; - - locale_charset = e_iconv_locale_charset (); - - out = g_string_new (""); + + locale_charset = e_iconv_locale_charset(); + + out = g_string_new(""); inptr = in; inend = inptr + inlen; chunk = NULL; @@ -1223,11 +1238,11 @@ rfc2047_encode_word(GString *outstring, const char *in, size_t len, const char * /* convert utf8->encoding */ bufflen = len * 6 + 16; - buffer = g_alloca (bufflen); + buffer = alloca (bufflen); inlen = len; inptr = in; - ascii = g_alloca (bufflen); + ascii = alloca (bufflen); if (strcasecmp (type, "UTF-8") != 0) ic = e_iconv_open (type, "UTF-8"); @@ -1279,12 +1294,12 @@ rfc2047_encode_word(GString *outstring, const char *in, size_t len, const char * convlen = MIN(inlen, CAMEL_FOLD_PREENCODED); p = inptr; if (e_iconv (ic, &inptr, &convlen, &out, &outlen) == (size_t) -1) { - w(g_warning("Conversion problem: conversion truncated: %s", strerror (errno))); + w(g_warning("Conversion problem: conversion truncated: %s", strerror(errno))); /* blah, we include it anyway, better than infinite loop ... */ inptr = p + convlen; } else { /* make sure we flush out any shift state */ - e_iconv (ic, NULL, 0, &out, &outlen); + e_iconv(ic, NULL, 0, &out, &outlen); } inlen -= (inptr - p); } @@ -1309,7 +1324,7 @@ rfc2047_encode_word(GString *outstring, const char *in, size_t len, const char * } if (ic != (iconv_t) -1) - e_iconv_close (ic); + e_iconv_close(ic); } @@ -1561,8 +1576,6 @@ header_encode_phrase_get_words (const unsigned char *in) return words; } -#define MERGED_WORD_LT_FOLDLEN(wordlen, type) ((type) == WORD_2047 ? (wordlen) < CAMEL_FOLD_PREENCODED : (wordlen) < (CAMEL_FOLD_SIZE - 8)) - static gboolean header_encode_phrase_merge_words (GList **wordsp) { @@ -1580,15 +1593,13 @@ header_encode_phrase_merge_words (GList **wordsp) next = nextl->data; /* merge nodes of the same type AND we are not creating too long a string */ if (word_types_compatable (word->type, next->type)) { - if (MERGED_WORD_LT_FOLDLEN (next->end - word->start, MAX (word->type, next->type))) { + if (next->end - word->start < CAMEL_FOLD_PREENCODED) { /* the resulting word type is the MAX of the 2 types */ word->type = MAX(word->type, next->type); word->end = next->end; words = g_list_remove_link (words, nextl); - g_list_free_1 (nextl); g_free (next); - nextl = g_list_next (wordl); merged = TRUE; @@ -2338,7 +2349,7 @@ header_decode_addrspec(const char **in) */ static struct _header_address * -header_decode_mailbox(const char **in, const char *charset) +header_decode_mailbox(const char **in) { const char *inptr = *in; char *pre; @@ -2360,7 +2371,7 @@ header_decode_mailbox(const char **in, const char *charset) char *text, *last; /* perform internationalised decoding, and append */ - text = header_decode_string (pre, charset); + text = header_decode_string (pre, NULL); g_string_append (name, text); last = pre; g_free(text); @@ -2462,7 +2473,7 @@ header_decode_mailbox(const char **in, const char *charset) g_string_append_c(addr, *inptr); /* check for address is encoded word ... */ - text = header_decode_string(addr->str, charset); + text = header_decode_string(addr->str, NULL); if (name == NULL) { name = addr; addr = g_string_new(""); @@ -2518,7 +2529,7 @@ header_decode_mailbox(const char **in, const char *charset) if (comend > comstart) { d(printf(" looking at subset '%.*s'\n", comend-comstart, comstart)); tmp = g_strndup (comstart, comend-comstart); - text = header_decode_string (tmp, charset); + text = header_decode_string (tmp, NULL); name = g_string_new (text); g_free (tmp); g_free (text); @@ -2541,7 +2552,7 @@ header_decode_mailbox(const char **in, const char *charset) } static struct _header_address * -header_decode_address(const char **in, const char *charset) +header_decode_address(const char **in) { const char *inptr = *in; char *pre; @@ -2566,7 +2577,7 @@ header_decode_address(const char **in, const char *charset) if (*inptr != ';') { int go = TRUE; do { - member = header_decode_mailbox(&inptr, charset); + member = header_decode_mailbox(&inptr); if (member) header_address_add_member(addr, member); header_decode_lwsp(&inptr); @@ -2585,7 +2596,7 @@ header_decode_address(const char **in, const char *charset) } *in = inptr; } else { - addr = header_decode_mailbox(in, charset); + addr = header_decode_mailbox(in); } g_string_free(group, TRUE); @@ -2811,16 +2822,16 @@ header_references_dup(const struct _header_references *list) } struct _header_address * -header_mailbox_decode(const char *in, const char *charset) +header_mailbox_decode(const char *in) { if (in == NULL) return NULL; - return header_decode_mailbox(&in, charset); + return header_decode_mailbox(&in); } struct _header_address * -header_address_decode(const char *in, const char *charset) +header_address_decode(const char *in) { const char *inptr = in, *last; struct _header_address *list = NULL, *addr; @@ -2836,7 +2847,7 @@ header_address_decode(const char *in, const char *charset) do { last = inptr; - addr = header_decode_address(&inptr, charset); + addr = header_decode_address(&inptr); if (addr) header_address_list_append(&list, addr); header_decode_lwsp(&inptr); @@ -3055,7 +3066,7 @@ header_encode_param (const unsigned char *in, gboolean *encoded) inbuf = in; if (e_iconv (cd, &inbuf, &inleft, &outptr, &outleft) == (size_t) -1) { - w(g_warning ("Conversion problem: conversion truncated: %s", strerror (errno))); + w(g_warning ("Conversion problem: conversion truncated: %s", g_strerror (errno))); } else { e_iconv (cd, NULL, 0, &outptr, &outleft); } @@ -3068,7 +3079,7 @@ header_encode_param (const unsigned char *in, gboolean *encoded) /* FIXME: set the 'language' as well, assuming we can get that info...? */ out = g_string_new (""); - g_string_append_printf (out, "%s''", charset); + g_string_sprintfa (out, "%s''", charset); while (inptr < inend) { unsigned char c = *inptr++; @@ -3076,9 +3087,9 @@ header_encode_param (const unsigned char *in, gboolean *encoded) /* FIXME: make sure that '\'', '*', and ';' are also encoded */ if (c > 127) { - g_string_append_printf (out, "%%%c%c", tohex[(c >> 4) & 0xf], tohex[c & 0xf]); + g_string_sprintfa (out, "%%%c%c", tohex[(c >> 4) & 0xf], tohex[c & 0xf]); } else if (is_lwsp (c) || !(camel_mime_special_table[c] & IS_ESAFE)) { - g_string_append_printf (out, "%%%c%c", tohex[(c >> 4) & 0xf], tohex[c & 0xf]); + g_string_sprintfa (out, "%%%c%c", tohex[(c >> 4) & 0xf], tohex[c & 0xf]); } else { g_string_append_c (out, c); } @@ -3165,7 +3176,7 @@ header_param_list_format_append (GString *out, struct _header_param *p) used = 0; } - g_string_append_printf (out, "%s*%d%s=", p->name, i++, encoded ? "*" : ""); + g_string_sprintfa (out, "%s*%d%s=", p->name, i++, encoded ? "*" : ""); if (encoded || !quote) g_string_append_len (out, inptr, ptr - inptr); else @@ -3178,7 +3189,7 @@ header_param_list_format_append (GString *out, struct _header_param *p) inptr = ptr; } } else { - g_string_append_printf (out, "%s%s=", p->name, encoded ? "*" : ""); + g_string_sprintfa (out, "%s%s=", p->name, encoded ? "*" : ""); if (encoded || !quote) g_string_append (out, value); @@ -3264,32 +3275,31 @@ header_content_type_dump(struct _header_content_type *ct) } char * -header_content_type_format (struct _header_content_type *ct) +header_content_type_format(struct _header_content_type *ct) { GString *out; char *ret; - - if (ct == NULL) + + if (ct==NULL) return NULL; - - out = g_string_new (""); + + out = g_string_new(""); if (ct->type == NULL) { - g_string_append_printf (out, "text/plain"); - w(g_warning ("Content-Type with no main type")); + g_string_sprintfa(out, "text/plain"); + w(g_warning("Content-Type with no main type")); } else if (ct->subtype == NULL) { - w(g_warning ("Content-Type with no sub type: %s", ct->type)); - if (!strcasecmp (ct->type, "multipart")) - g_string_append_printf (out, "%s/mixed", ct->type); + w(g_warning("Content-Type with no sub type: %s", ct->type)); + if (!strcasecmp(ct->type, "multipart")) + g_string_sprintfa(out, "%s/mixed", ct->type); else - g_string_append_printf (out, "%s", ct->type); + g_string_sprintfa(out, "%s", ct->type); } else { - g_string_append_printf (out, "%s/%s", ct->type, ct->subtype); + g_string_sprintfa(out, "%s/%s", ct->type, ct->subtype); } - header_param_list_format_append (out, ct->params); - + header_param_list_format_append(out, ct->params); + ret = out->str; - g_string_free (out, FALSE); - + g_string_free(out, FALSE); return ret; } @@ -3617,7 +3627,7 @@ header_raw_append_parse(struct _header_raw **list, const char *header, int offse printf("Invalid header line: '%s'\n", header); return; } - name = g_alloca (fieldlen + 1); + name = alloca(fieldlen+1); memcpy(name, header, fieldlen); name[fieldlen] = 0; @@ -4002,10 +4012,10 @@ void header_address_list_clear(struct _header_address **l) /* if encode is true, then the result is suitable for mailing, otherwise the result is suitable for display only (and may not even be re-parsable) */ static void -header_address_list_encode_append (GString *out, int encode, struct _header_address *a) +header_address_list_encode_append(GString *out, int encode, struct _header_address *a) { char *text; - + while (a) { switch (a->type) { case HEADER_ADDRESS_NAME: @@ -4014,65 +4024,64 @@ header_address_list_encode_append (GString *out, int encode, struct _header_addr else text = a->name; if (text && *text) - g_string_append_printf (out, "%s <%s>", text, a->v.addr); + g_string_sprintfa(out, "%s <%s>", text, a->v.addr); else - g_string_append (out, a->v.addr); + g_string_append(out, a->v.addr); if (encode) - g_free (text); + g_free(text); break; case HEADER_ADDRESS_GROUP: if (encode) - text = header_encode_phrase (a->name); + text = header_encode_phrase(a->name); else text = a->name; - g_string_append_printf (out, "%s: ", text); - header_address_list_encode_append (out, encode, a->v.members); - g_string_append_printf (out, ";"); + g_string_sprintfa(out, "%s: ", text); + header_address_list_encode_append(out, encode, a->v.members); + g_string_sprintfa(out, ";"); if (encode) - g_free (text); + g_free(text); break; default: - g_warning ("Invalid address type"); + g_warning("Invalid address type"); break; } a = a->next; if (a) - g_string_append (out, ", "); + g_string_append(out, ", "); } } char * -header_address_list_encode (struct _header_address *a) +header_address_list_encode(struct _header_address *a) { GString *out; char *ret; - + if (a == NULL) return NULL; - - out = g_string_new (""); - header_address_list_encode_append (out, TRUE, a); + + out = g_string_new(""); + + header_address_list_encode_append(out, TRUE, a); ret = out->str; - g_string_free (out, FALSE); - + g_string_free(out, FALSE); return ret; } char * -header_address_list_format (struct _header_address *a) +header_address_list_format(struct _header_address *a) { GString *out; char *ret; - + if (a == NULL) return NULL; - - out = g_string_new (""); - - header_address_list_encode_append (out, FALSE, a); + + out = g_string_new(""); + + header_address_list_encode_append(out, FALSE, a); ret = out->str; - g_string_free (out, FALSE); - + g_string_free(out, FALSE); return ret; } |