X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=rfc2047.c;h=a181e9dd3488ef2fa8602fb803c0071f888b0d9b;hp=7fc21d004a73414c9fa45c10e288fe47714a59d5;hb=ab12fea9d01b3b9bc53081ae4ccc046243f1cb9f;hpb=bbc4fd52516a8afefbd14c77e34f8389d6f0a6ed diff --git a/rfc2047.c b/rfc2047.c index 7fc21d0..a181e9d 100644 --- a/rfc2047.c +++ b/rfc2047.c @@ -12,14 +12,17 @@ # include "config.h" #endif +#include +#include +#include + +#include + #include "mutt.h" -#include "ascii.h" -#include "mime.h" #include "charset.h" #include "rfc2047.h" +#include "thread.h" -#include "lib/mem.h" -#include "lib/str.h" #include #include @@ -37,18 +40,16 @@ #endif #define ENCWORD_LEN_MAX 75 -#define ENCWORD_LEN_MIN 9 /* str_len ("=?.?.?.?=") */ +#define ENCWORD_LEN_MIN 9 /* m_strlen("=?.?.?.?=") */ #define HSPACE(x) ((x) == '\0' || (x) == ' ' || (x) == '\t') #define CONTINUATION_BYTE(c) (((c) & 0xc0) == 0x80) -extern char RFC822Specials[]; - -typedef size_t (*encoder_t) (char *, ICONV_CONST char *, size_t, +typedef size_t (*encoder_t) (char *, const char *, size_t, const char *); -static size_t convert_string (ICONV_CONST char *f, size_t flen, +static size_t convert_string (const char *f, size_t flen, const char *from, const char *to, char **t, size_t * tlen) { @@ -61,11 +62,11 @@ static size_t convert_string (ICONV_CONST char *f, size_t flen, if (cd == (iconv_t) (-1)) return (size_t) (-1); obl = 4 * flen + 1; - ob = buf = mem_malloc (obl); - n = iconv (cd, &f, &flen, &ob, &obl); - if (n == (size_t) (-1) || iconv (cd, 0, 0, &ob, &obl) == (size_t) (-1)) { + ob = buf = p_new(char, obl); + n = my_iconv(cd, &f, &flen, &ob, &obl); + if (n == (size_t) (-1) || my_iconv(cd, 0, 0, &ob, &obl) == (size_t) (-1)) { e = errno; - mem_free (&buf); + p_delete(&buf); iconv_close (cd); errno = e; return (size_t) (-1); @@ -74,7 +75,7 @@ static size_t convert_string (ICONV_CONST char *f, size_t flen, *tlen = ob - buf; - mem_realloc (&buf, ob - buf + 1); + p_realloc(&buf, ob - buf + 1); *t = buf; iconv_close (cd); @@ -95,7 +96,7 @@ char *mutt_choose_charset (const char *fromcode, const char *charsets, q = strchr (p, ':'); - n = q ? q - p : str_len (p); + n = q ? q - p : m_strlen(p); if (!n || /* Assume that we never need more than 12 characters of @@ -103,9 +104,7 @@ char *mutt_choose_charset (const char *fromcode, const char *charsets, n > (ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 2 - 12)) continue; - t = mem_malloc (n + 1); - memcpy (t, p, n); - t[n] = '\0'; + t = p_dupstr(p, n); n = convert_string (u, ulen, fromcode, t, &s, &slen); if (n == (size_t) (-1)) @@ -113,21 +112,21 @@ char *mutt_choose_charset (const char *fromcode, const char *charsets, if (!tocode || n < bestn) { bestn = n; - mem_free (&tocode); + p_delete(&tocode); tocode = t; if (d) { - mem_free (&e); + p_delete(&e); e = s; } else - mem_free (&s); + p_delete(&s); elen = slen; if (!bestn) break; } else { - mem_free (&t); - mem_free (&s); + p_delete(&t); + p_delete(&s); } } if (tocode) { @@ -142,36 +141,36 @@ char *mutt_choose_charset (const char *fromcode, const char *charsets, return tocode; } -static size_t b_encoder (char *s, ICONV_CONST char *d, size_t dlen, +static size_t b_encoder (char *s, const char *d, size_t dlen, const char *tocode) { char *s0 = s; memcpy (s, "=?", 2), s += 2; - memcpy (s, tocode, str_len (tocode)), s += str_len (tocode); + memcpy (s, tocode, m_strlen(tocode)), s += m_strlen(tocode); memcpy (s, "?B?", 3), s += 3; for (;;) { if (!dlen) break; else if (dlen == 1) { - *s++ = B64Chars[(*d >> 2) & 0x3f]; - *s++ = B64Chars[(*d & 0x03) << 4]; + *s++ = __m_b64chars[(*d >> 2) & 0x3f]; + *s++ = __m_b64chars[(*d & 0x03) << 4]; *s++ = '='; *s++ = '='; break; } else if (dlen == 2) { - *s++ = B64Chars[(*d >> 2) & 0x3f]; - *s++ = B64Chars[((*d & 0x03) << 4) | ((d[1] >> 4) & 0x0f)]; - *s++ = B64Chars[(d[1] & 0x0f) << 2]; + *s++ = __m_b64chars[(*d >> 2) & 0x3f]; + *s++ = __m_b64chars[((*d & 0x03) << 4) | ((d[1] >> 4) & 0x0f)]; + *s++ = __m_b64chars[(d[1] & 0x0f) << 2]; *s++ = '='; break; } else { - *s++ = B64Chars[(*d >> 2) & 0x3f]; - *s++ = B64Chars[((*d & 0x03) << 4) | ((d[1] >> 4) & 0x0f)]; - *s++ = B64Chars[((d[1] & 0x0f) << 2) | ((d[2] >> 6) & 0x03)]; - *s++ = B64Chars[d[2] & 0x3f]; + *s++ = __m_b64chars[(*d >> 2) & 0x3f]; + *s++ = __m_b64chars[((*d & 0x03) << 4) | ((d[1] >> 4) & 0x0f)]; + *s++ = __m_b64chars[((d[1] & 0x0f) << 2) | ((d[2] >> 6) & 0x03)]; + *s++ = __m_b64chars[d[2] & 0x3f]; d += 3, dlen -= 3; } } @@ -179,14 +178,14 @@ static size_t b_encoder (char *s, ICONV_CONST char *d, size_t dlen, return s - s0; } -static size_t q_encoder (char *s, ICONV_CONST char *d, size_t dlen, +static size_t q_encoder (char *s, const char *d, size_t dlen, const char *tocode) { char hex[] = "0123456789ABCDEF"; char *s0 = s; memcpy (s, "=?", 2), s += 2; - memcpy (s, tocode, str_len (tocode)), s += str_len (tocode); + memcpy (s, tocode, m_strlen(tocode)), s += m_strlen(tocode); memcpy (s, "?Q?", 3), s += 3; while (dlen--) { unsigned char c = *d++; @@ -214,13 +213,13 @@ static size_t q_encoder (char *s, ICONV_CONST char *d, size_t dlen, * tocode, unless fromcode is 0, in which case the data is assumed to * be already in tocode, which should be 8-bit and stateless. */ -static size_t try_block (ICONV_CONST char *d, size_t dlen, +static size_t try_block (const char *d, size_t dlen, const char *fromcode, const char *tocode, encoder_t * encoder, size_t * wlen) { char buf1[ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 1]; iconv_t cd; - ICONV_CONST char *ib; + const char *ib; char *ob, *p; size_t ibl, obl; int count, len, len_b, len_q; @@ -228,9 +227,9 @@ static size_t try_block (ICONV_CONST char *d, size_t dlen, if (fromcode) { cd = mutt_iconv_open (tocode, fromcode, 0); assert (cd != (iconv_t) (-1)); - ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - str_len (tocode); - if (iconv (cd, &ib, &ibl, &ob, &obl) == (size_t) (-1) || - iconv (cd, 0, 0, &ob, &obl) == (size_t) (-1)) { + ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - m_strlen(tocode); + if (my_iconv(cd, &ib, &ibl, &ob, &obl) == (size_t) (-1) || + my_iconv(cd, 0, 0, &ob, &obl) == (size_t) (-1)) { assert (errno == E2BIG); iconv_close (cd); assert (ib > d); @@ -239,8 +238,8 @@ static size_t try_block (ICONV_CONST char *d, size_t dlen, iconv_close (cd); } else { - if (dlen > sizeof (buf1) - str_len (tocode)) - return sizeof (buf1) - str_len (tocode) + 1; + if (dlen > sizeof (buf1) - m_strlen(tocode)) + return sizeof (buf1) - m_strlen(tocode) + 1; memcpy (buf1, d, dlen); ob = buf1 + dlen; } @@ -255,7 +254,7 @@ static size_t try_block (ICONV_CONST char *d, size_t dlen, ++count; } - len = ENCWORD_LEN_MIN - 2 + str_len (tocode); + len = ENCWORD_LEN_MIN - 2 + m_strlen(tocode); len_b = len + (((ob - buf1) + 2) / 3) * 4; len_q = len + (ob - buf1) + 2 * count; @@ -287,16 +286,16 @@ static size_t encode_block (char *s, char *d, size_t dlen, { char buf1[ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 1]; iconv_t cd; - ICONV_CONST char *ib; + const char *ib; char *ob; size_t ibl, obl, n1, n2; if (fromcode) { cd = mutt_iconv_open (tocode, fromcode, 0); assert (cd != (iconv_t) (-1)); - ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - str_len (tocode); - n1 = iconv (cd, &ib, &ibl, &ob, &obl); - n2 = iconv (cd, 0, 0, &ob, &obl); + ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - m_strlen(tocode); + n1 = my_iconv(cd, &ib, &ibl, &ob, &obl); + n2 = my_iconv(cd, 0, 0, &ob, &obl); assert (n1 != (size_t) (-1) && n2 != (size_t) (-1)); iconv_close (cd); return (*encoder) (s, buf1, ob - buf1, tocode); @@ -343,7 +342,7 @@ static size_t choose_block (char *d, size_t dlen, int col, * The input data is assumed to be a single line starting at column col; * if col is non-zero, the preceding character was a space. */ -static int rfc2047_encode (ICONV_CONST char *d, size_t dlen, int col, +static int rfc2047_encode (const char *d, size_t dlen, int col, const char *fromcode, const char *charsets, char **e, size_t * elen, char *specials) { @@ -356,15 +355,13 @@ static int rfc2047_encode (ICONV_CONST char *d, size_t dlen, int col, encoder_t encoder; char *tocode1 = 0; const char *tocode; - char *icode = "UTF-8"; + const char *icode = "UTF-8"; /* Try to convert to UTF-8. */ if (convert_string (d, dlen, fromcode, icode, &u, &ulen)) { ret = 1; icode = 0; - u = mem_malloc ((ulen = dlen) + 1); - memcpy (u, d, dlen); - u[ulen] = 0; + u = p_dupstr(d, ulen = dlen); } /* Find earliest and latest things we must encode. */ @@ -447,7 +444,7 @@ static int rfc2047_encode (ICONV_CONST char *d, size_t dlen, int col, /* Initialise the output buffer with the us-ascii prefix. */ buflen = 2 * ulen; - buf = mem_malloc (buflen); + buf = p_new(char, buflen); bufpos = t0 - u; memcpy (buf, u, t0 - u); @@ -481,15 +478,15 @@ static int rfc2047_encode (ICONV_CONST char *d, size_t dlen, int col, /* Add to output buffer. */ #define LINEBREAK "\n\t" - if (bufpos + wlen + str_len (LINEBREAK) > buflen) { - buflen = bufpos + wlen + str_len (LINEBREAK); - mem_realloc (&buf, buflen); + if (bufpos + wlen + m_strlen(LINEBREAK) > buflen) { + buflen = bufpos + wlen + m_strlen(LINEBREAK); + p_realloc(&buf, buflen); } r = encode_block (buf + bufpos, t, n, icode, tocode, encoder); assert (r == wlen); bufpos += wlen; - memcpy (buf + bufpos, LINEBREAK, str_len (LINEBREAK)); - bufpos += str_len (LINEBREAK); + memcpy (buf + bufpos, LINEBREAK, m_strlen(LINEBREAK)); + bufpos += m_strlen(LINEBREAK); #undef LINEBREAK col = 1; @@ -499,14 +496,14 @@ static int rfc2047_encode (ICONV_CONST char *d, size_t dlen, int col, /* Add last encoded word and us-ascii suffix to buffer. */ buflen = bufpos + wlen + (u + ulen - t1); - mem_realloc (&buf, buflen + 1); + p_realloc(&buf, buflen + 1); r = encode_block (buf + bufpos, t, t1 - t, icode, tocode, encoder); assert (r == wlen); bufpos += wlen; memcpy (buf + bufpos, t1, u + ulen - t1); - mem_free (&tocode1); - mem_free (&u); + p_delete(&tocode1); + p_delete(&u); buf[buflen] = '\0'; @@ -519,7 +516,7 @@ void _rfc2047_encode_string (char **pd, int encode_specials, int col) { char *e; size_t elen; - char *charsets; + const char *charsets; if (!Charset || !*pd) return; @@ -528,18 +525,18 @@ void _rfc2047_encode_string (char **pd, int encode_specials, int col) if (!charsets || !*charsets) charsets = "UTF-8"; - rfc2047_encode (*pd, str_len (*pd), col, + rfc2047_encode (*pd, m_strlen(*pd), col, Charset, charsets, &e, &elen, encode_specials ? RFC822Specials : NULL); - mem_free (pd); + p_delete(pd); *pd = e; } void rfc2047_encode_adrlist (ADDRESS * addr, const char *tag) { ADDRESS *ptr = addr; - int col = tag ? str_len (tag) + 2 : 32; + int col = tag ? m_strlen(tag) + 2 : 32; while (ptr) { if (ptr->personal) @@ -556,7 +553,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) int enc = 0, count = 0; char *charset = NULL; - pd = d0 = mem_malloc (str_len (s)); + pd = d0 = p_new(char, m_strlen(s)); for (pp = s; (pp1 = strchr (pp, '?')); pp = pp1 + 1) { count++; @@ -566,9 +563,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) t = pp1; if ((t1 = memchr (pp, '*', t - pp))) t = t1; - charset = mem_malloc (t - pp + 1); - memcpy (charset, pp, t - pp); - charset[t - pp] = '\0'; + charset = p_dupstr(pp, t - pp); break; case 3: if (toupper ((unsigned char) *pp) == 'Q') @@ -576,8 +571,8 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) else if (toupper ((unsigned char) *pp) == 'B') enc = ENCBASE64; else { - mem_free (&charset); - mem_free (&d0); + p_delete(&charset); + p_delete(&d0); return (-1); } break; @@ -586,9 +581,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) for (; pp < pp1; pp++) { if (*pp == '_') *pd++ = ' '; - else if (*pp == '=' && - (!(pp[1] & ~127) && hexval (pp[1]) != -1) && - (!(pp[2] & ~127) && hexval (pp[2]) != -1)) { + else if (*pp == '=' && hexval(pp[1]) >= 0 && hexval(pp[2]) >= 0) { *pd++ = (hexval (pp[1]) << 4) | hexval (pp[2]); pp += 2; } @@ -603,7 +596,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) for (; pp < pp1; pp++) { if (*pp == '=') break; - if ((*pp & ~127) || (c = base64val (*pp)) == -1) + if ((c = base64val(*pp)) < 0) continue; if (k + 6 >= 8) { k -= 2; @@ -623,9 +616,9 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) if (charset) mutt_convert_string (&d0, charset, Charset, M_ICONV_HOOK_FROM); - strfcpy (d, d0, len); - mem_free (&charset); - mem_free (&d0); + m_strcpy(d, len, d0); + p_delete(&charset); + p_delete(&d0); return (0); } @@ -712,14 +705,14 @@ void rfc2047_decode (char **pd) if (!s || !*s) return; - dlen = 4 * str_len (s); /* should be enough */ - d = d0 = mem_malloc (dlen + 1); + dlen = 4 * m_strlen(s); /* should be enough */ + d = d0 = p_new(char, dlen + 1); while (*s && dlen > 0) { if (!(p = find_encoded_word (s, &q))) { /* no encoded words */ if (!option (OPTSTRICTMIME)) { - n = str_len (s); + n = m_strlen(s); if (found_encoded && (m = lwslen (s, n)) != 0) { if (m != n) *d = ' ', d++, dlen--; @@ -729,10 +722,9 @@ void rfc2047_decode (char **pd) char *t; size_t tlen; - t = mem_malloc (n + 1); - strfcpy (t, s, n + 1); + t = p_dupstr(s, n); if (mutt_convert_nonmime_string (&t) == 0) { - tlen = str_len (t); + tlen = m_strlen(t); strncpy (d, t, tlen); d += tlen; } @@ -740,7 +732,7 @@ void rfc2047_decode (char **pd) strncpy (d, s, n); d += n; } - mem_free (&t); + p_delete(&t); break; } } @@ -782,13 +774,13 @@ void rfc2047_decode (char **pd) rfc2047_decode_word (d, p, dlen); found_encoded = 1; s = q; - n = str_len (d); + n = m_strlen(d); dlen -= n; d += n; } *d = 0; - mem_free (pd); + p_delete(pd); *pd = d0; str_adjust (pd); } @@ -801,3 +793,24 @@ void rfc2047_decode_adrlist (ADDRESS * a) a = a->next; } } + +void rfc2047_decode_envelope (ENVELOPE* e) { + + if (!e) + return; + + /* do RFC2047 decoding */ + rfc2047_decode_adrlist (e->from); + rfc2047_decode_adrlist (e->to); + rfc2047_decode_adrlist (e->cc); + rfc2047_decode_adrlist (e->bcc); + rfc2047_decode_adrlist (e->reply_to); + rfc2047_decode_adrlist (e->mail_followup_to); + rfc2047_decode_adrlist (e->return_path); + rfc2047_decode_adrlist (e->sender); + + if (e->subject) { + rfc2047_decode (&e->subject); + mutt_adjust_subject (e); + } +}