From b2ae7c03f2b772f2663768931ef51ff7aa1caf33 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sat, 4 Nov 2006 14:44:00 +0100 Subject: [PATCH] more coding rules, simplifications. Signed-off-by: Pierre Habouzit --- lib-mime/rfc2047.c | 226 +++++++++++++++++++++++++-------------------- 1 file changed, 126 insertions(+), 100 deletions(-) diff --git a/lib-mime/rfc2047.c b/lib-mime/rfc2047.c index a18b190..c28b2b9 100644 --- a/lib-mime/rfc2047.c +++ b/lib-mime/rfc2047.c @@ -380,10 +380,6 @@ static size_t choose_block(char *d, size_t dlen, int col, return n; } - - -/*** XXX: MC: not read after that mark ***/ - /* * Place the result of RFC-2047-encoding (d, dlen) into the dynamically * allocated buffer (e, elen). The input data is in charset fromcode @@ -394,30 +390,31 @@ 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 (const char *d, ssize_t dlen, int col, - const char *fromcode, const char *charsets, - char **e, ssize_t *elen, const char *specials) +/*** XXX: simplify that one day ***/ +static int rfc2047_encode(const char *d, ssize_t dlen, int col, + const char *fromcode, const char *charsets, + char **e, ssize_t *elen, const char *specials) { int ret = 0; char *buf; ssize_t bufpos, buflen; - char *u, *t0, *t1, *t; - char *s0, *s1; - ssize_t ulen, r, n, wlen; - encoder_t *encoder; + char *u, *t; + char *s0, *s1, *t0, *t1; char *tocode1 = 0; const char *tocode; const char *icode = "UTF-8"; + ssize_t ulen, r, n, wlen; + encoder_t *encoder; /* Try to convert to UTF-8. */ if (convert_string(fromcode, d, dlen, icode, &u, &ulen)) { ret = 1; - icode = 0; + icode = NULL; u = p_dupstr(d, ulen = dlen); } /* Find earliest and latest things we must encode. */ - s0 = s1 = t0 = t1 = 0; + s0 = s1 = t0 = t1 = NULL; for (t = u; t < u + ulen; t++) { if ((*t & 0x80) || (*t == '=' && t[1] == '?' && (t == u || HSPACE (*(t - 1))))) { @@ -456,7 +453,7 @@ static int rfc2047_encode (const char *d, ssize_t dlen, int col, } /* Hack to avoid labelling 8-bit data as us-ascii. */ - if (!icode && mutt_is_us_ascii (tocode)) + if (!icode && mutt_is_us_ascii(tocode)) tocode = "unknown-8bit"; /* Adjust t0 for maximum length of line. */ @@ -469,27 +466,29 @@ static int rfc2047_encode (const char *d, ssize_t dlen, int col, /* Adjust t0 until we can encode a character after a space. */ for (; t0 > u; t0--) { - if (!HSPACE (*(t0 - 1))) + if (!HSPACE(t0[-1])) continue; t = t0 + 1; - if (icode) - while (t < u + ulen && CONTINUATION_BYTE (*t)) + if (icode) { + while (t < u + ulen && CONTINUATION_BYTE(*t)) ++t; - if (!try_block (t0, t - t0, icode, tocode, &encoder, &wlen) && - col + (t0 - u) + wlen <= ENCWORD_LEN_MAX + 1) + } + if (!try_block(t0, t - t0, icode, tocode, &encoder, &wlen) + && col + (t0 - u) + wlen <= ENCWORD_LEN_MAX + 1) break; } /* Adjust t1 until we can encode a character before a space. */ for (; t1 < u + ulen; t1++) { - if (!HSPACE (*t1)) + if (!HSPACE(*t1)) continue; t = t1 - 1; - if (icode) - while (CONTINUATION_BYTE (*t)) + if (icode) { + while (CONTINUATION_BYTE(*t)) --t; - if (!try_block (t, t1 - t, icode, tocode, &encoder, &wlen) && - 1 + wlen + (u + ulen - t1) <= ENCWORD_LEN_MAX + 1) + } + if (!try_block (t, t1 - t, icode, tocode, &encoder, &wlen) + && 1 + wlen + (u + ulen - t1) <= ENCWORD_LEN_MAX + 1) break; } @@ -499,7 +498,7 @@ static int rfc2047_encode (const char *d, ssize_t dlen, int col, buflen = 2 * ulen; buf = p_new(char, buflen); bufpos = t0 - u; - memcpy (buf, u, t0 - u); + memcpy(buf, u, t0 - u); col += t0 - u; @@ -531,8 +530,8 @@ static int rfc2047_encode (const char *d, ssize_t dlen, int col, /* Add to output buffer. */ #define LINEBREAK "\n\t" - if (bufpos + wlen + m_strlen(LINEBREAK) > buflen) { - buflen = bufpos + wlen + m_strlen(LINEBREAK); + if (bufpos + wlen + 2 > buflen) { + buflen = bufpos + wlen + 2; p_realloc(&buf, buflen); } r = encode_block (buf + bufpos, t, n, icode, tocode, encoder); @@ -565,7 +564,8 @@ static int rfc2047_encode (const char *d, ssize_t dlen, int col, return ret; } -void _rfc2047_encode_string (char **pd, int encode_specials, int col) + +void _rfc2047_encode_string(char **pd, int encode_specials, int col) { char *e; ssize_t elen; @@ -574,13 +574,11 @@ void _rfc2047_encode_string (char **pd, int encode_specials, int col) if (!Charset || !*pd) return; - charsets = SendCharset; - if (!charsets || !*charsets) - charsets = "UTF-8"; + charsets = m_strisempty(SendCharset) ? "UTF-8" : SendCharset; - rfc2047_encode (*pd, m_strlen(*pd), col, - Charset, charsets, &e, &elen, - encode_specials ? RFC822Specials : NULL); + rfc2047_encode(*pd, m_strlen(*pd), col, + Charset, charsets, &e, &elen, + encode_specials ? RFC822Specials : NULL); p_delete(pd); *pd = e; @@ -590,93 +588,108 @@ void rfc2047_encode_string(char **pd) { _rfc2047_encode_string(pd, 0, 32); } -void rfc2047_encode_adrlist (address_t * addr, const char *tag) +void rfc2047_encode_adrlist(address_t *addr, const char *tag) { address_t *ptr = addr; int col = tag ? m_strlen(tag) + 2 : 32; while (ptr) { if (ptr->personal) - _rfc2047_encode_string (&ptr->personal, 1, col); + _rfc2047_encode_string(&ptr->personal, 1, col); ptr = ptr->next; } } -static int rfc2047_decode_word (char *d, const char *s, size_t len) + +/****************************************************************************/ +/* Decoding functions */ +/****************************************************************************/ + +/* decode one word into d[len] */ +static int rfc2047_decode_word(char *d, size_t len, const char *s) { - const char *pp, *pp1; - char *pd, *d0; - const char *t, *t1; - int enc = 0, count = 0; + const char *p, *eotoken; char *charset = NULL; + int enc = 0, count = 0; + char *d0; - pd = d0 = p_new(char, m_strlen(s)); + /* =?[QB]?cset?.?= */ + for (p = s; (eotoken = strchr(p, '?')); p = eotoken + 1) { + switch (++count) { + const char *t; + char *q; - for (pp = s; (pp1 = strchr (pp, '?')); pp = pp1 + 1) { - count++; - switch (count) { case 2: /* ignore language specification a la RFC 2231 */ - t = pp1; - if ((t1 = memchr (pp, '*', t - pp))) - t = t1; - charset = p_dupstr(pp, t - pp); + t = memchr(p, '*', eotoken - p) ?: eotoken; + charset = p_dupstr(p, t - p); break; + case 3: - if (toupper ((unsigned char) *pp) == 'Q') + switch (*p) { + case 'q': case 'Q': enc = ENCQUOTEDPRINTABLE; - else if (toupper ((unsigned char) *pp) == 'B') + break; + + case 'b': case 'B': enc = ENCBASE64; - else { + break; + + default: p_delete(&charset); - p_delete(&d0); - return (-1); + return -1; } break; + case 4: + d0 = q = p_new(char, m_strlen(s) + 1); + if (enc == ENCQUOTEDPRINTABLE) { - for (; pp < pp1; pp++) { - if (*pp == '_') - *pd++ = ' '; - else if (*pp == '=' && hexval(pp[1]) >= 0 && hexval(pp[2]) >= 0) { - *pd++ = (hexval (pp[1]) << 4) | hexval (pp[2]); - pp += 2; + while (p < eotoken) { + if (*p == '=' && hexval(p[1]) >= 0 && hexval(p[2]) >= 0) { + *q++ = (hexval (p[1]) << 4) | hexval (p[2]); + p += 3; + } else + if (*p == '_') { + *q++ = ' '; + p++; + } else { + *q++ = *p++; } - else - *pd++ = *pp; } - *pd = 0; - } - else if (enc == ENCBASE64) { + *q = 0; + } else { /* enc == ENCBASE64 */ int c, b = 0, k = 0; - for (; pp < pp1; pp++) { - if (*pp == '=') + while (p < eotoken) { + if (*p == '=') break; - if ((c = base64val(*pp)) < 0) + + c = base64val(*p++); + if (c < 0) continue; + if (k + 6 >= 8) { k -= 2; - *pd++ = b | (c >> k); + *q++ = b | (c >> k); b = c << (8 - k); - } - else { + } else { b |= c << (k + 2); k += 6; } } - *pd = 0; + *q = 0; } break; } } if (charset) - mutt_convert_string (&d0, charset, Charset, M_ICONV_HOOK_FROM); + mutt_convert_string(&d0, charset, Charset, M_ICONV_HOOK_FROM); m_strcpy(d, len, d0); p_delete(&charset); p_delete(&d0); - return (0); + return 0; } /* @@ -685,50 +698,60 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) * must be B or Q. Also, we don't require the encoded word to be * separated by linear-white-space (section 5(1)). */ -static const char *find_encoded_word (const char *s, const char **x) +static const char *find_encoded_word(const char *s, const char **x) { - const char *p, *q; + const char *p; + + while ((p = strstr(s, "=?"))) { + s = p + 2; + while (0x20 < *s && *s < 0x7f && !strchr ("()<>@,;:\"/[]?.=", *s)) { + s++; + } - q = s; - while ((p = strstr (q, "=?"))) { - for (q = p + 2; - 0x20 < *q && *q < 0x7f && !strchr ("()<>@,;:\"/[]?.=", *q); q++); - if (q[0] != '?' || !strchr ("BbQq", q[1]) || q[2] != '?') + if (s[0] != '?' || !strchr("BbQq", s[1]) || s[2] != '?') continue; - for (q = q + 3; 0x20 <= *q && *q < 0x7f && *q != '?'; q++); - if (q[0] != '?' || q[1] != '=') { - --q; + + s += 3; + while (0x20 <= *s && *s < 0x7f && *s != '?') { + s++; + } + + if (s[0] != '?' || s[1] != '=') { + --s; continue; } - *x = q + 2; + *x = s + 2; return p; } - return 0; + return NULL; } /* return length of linear white space */ -static size_t lwslen (const char *s, size_t n) +static ssize_t lwslen(const char *s, ssize_t n) { - const char *p = s; - size_t len = n; + const char *p; + ssize_t len = n; if (n <= 0) return 0; - for (; p < s + n; p++) + for (p = s; p < s + n; p++) { if (!strchr (" \t\r\n", *p)) { - len = (size_t) (p - s); + len = p - s; break; } - if (strchr ("\r\n", *(p - 1))) /* LWS doesn't end with CRLF */ - len = (size_t) 0; + } + + if (p[-1] == '\r' || p[-1] == '\n') /* LWS cannot end with CRLF */ + return 0; + return len; } /* return length of linear white space : reverse */ -static size_t lwsrlen (const char *s, size_t n) +static ssize_t lwsrlen(const char *s, ssize_t n) { const char *p = s + n - 1; size_t len = n; @@ -736,14 +759,17 @@ static size_t lwsrlen (const char *s, size_t n) if (n <= 0) return 0; - if (strchr ("\r\n", *p)) /* LWS doesn't end with CRLF */ - return (size_t) 0; + if (*p == '\r' || *p == '\n') /* LWS doesn't end with CRLF */ + return 0; - for (; p >= s; p--) - if (!strchr (" \t\r\n", *p)) { - len = (size_t) (s + n - 1 - p); + while (p >= s) { + if (!strchr(" \t\r\n", *p)) { + len = s + n - 1 - p; break; } + p--; + } + return len; } @@ -828,7 +854,7 @@ void rfc2047_decode (char **pd) } } - rfc2047_decode_word (d, p, dlen); + rfc2047_decode_word(d, dlen, p); found_encoded = 1; s = q; n = m_strlen(d); -- 2.20.1