Signed-off-by: Pierre Habouzit <madcoder@debian.org>
-
-
-/*** 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
/*
* Place the result of RFC-2047-encoding (d, dlen) into the dynamically
* allocated buffer (e, elen). The input data is in charset fromcode
* 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.
*/
* 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;
{
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";
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;
/* Try to convert to UTF-8. */
if (convert_string(fromcode, d, dlen, icode, &u, &ulen)) {
ret = 1;
u = p_dupstr(d, ulen = dlen);
}
/* Find earliest and latest things we must encode. */
u = p_dupstr(d, ulen = dlen);
}
/* Find earliest and latest things we must encode. */
+ s0 = s1 = t0 = t1 = NULL;
for (t = u; t < u + ulen; t++) {
if ((*t & 0x80) ||
(*t == '=' && t[1] == '?' && (t == u || HSPACE (*(t - 1))))) {
for (t = u; t < u + ulen; t++) {
if ((*t & 0x80) ||
(*t == '=' && t[1] == '?' && (t == u || HSPACE (*(t - 1))))) {
}
/* Hack to avoid labelling 8-bit data as us-ascii. */
}
/* 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. */
tocode = "unknown-8bit";
/* Adjust t0 for maximum length of line. */
/* Adjust t0 until we can encode a character after a space. */
for (; t0 > u; t0--) {
/* Adjust t0 until we can encode a character after a space. */
for (; t0 > u; t0--) {
- if (!HSPACE (*(t0 - 1)))
- if (icode)
- while (t < u + ulen && CONTINUATION_BYTE (*t))
+ if (icode) {
+ while (t < u + ulen && CONTINUATION_BYTE(*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++) {
break;
}
/* Adjust t1 until we can encode a character before a space. */
for (; t1 < u + ulen; t1++) {
- if (icode)
- while (CONTINUATION_BYTE (*t))
+ if (icode) {
+ while (CONTINUATION_BYTE(*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)
buflen = 2 * ulen;
buf = p_new(char, buflen);
bufpos = t0 - u;
buflen = 2 * ulen;
buf = p_new(char, buflen);
bufpos = t0 - u;
- memcpy (buf, u, t0 - u);
+ memcpy(buf, u, t0 - u);
/* Add to output buffer. */
#define LINEBREAK "\n\t"
/* 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);
p_realloc(&buf, buflen);
}
r = encode_block (buf + bufpos, t, n, icode, tocode, encoder);
-void _rfc2047_encode_string (char **pd, int encode_specials, int col)
+
+void _rfc2047_encode_string(char **pd, int encode_specials, int col)
if (!Charset || !*pd)
return;
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);
_rfc2047_encode_string(pd, 0, 32);
}
_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)
{
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);
-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;
+ 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 */
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);
- if (toupper ((unsigned char) *pp) == 'Q')
+ switch (*p) {
+ case 'q': case 'Q':
enc = ENCQUOTEDPRINTABLE;
enc = ENCQUOTEDPRINTABLE;
- else if (toupper ((unsigned char) *pp) == 'B')
+ break;
+
+ case 'b': case 'B':
- p_delete(&d0);
- return (-1);
+ d0 = q = p_new(char, m_strlen(s) + 1);
+
if (enc == ENCQUOTEDPRINTABLE) {
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++;
- *pd = 0;
- }
- else if (enc == ENCBASE64) {
+ *q = 0;
+ } else { /* enc == ENCBASE64 */
- for (; pp < pp1; pp++) {
- if (*pp == '=')
+ while (p < eotoken) {
+ if (*p == '=')
- if ((c = base64val(*pp)) < 0)
+
+ c = base64val(*p++);
+ if (c < 0)
if (k + 6 >= 8) {
k -= 2;
if (k + 6 >= 8) {
k -= 2;
b |= c << (k + 2);
k += 6;
}
}
b |= c << (k + 2);
k += 6;
}
}
}
break;
}
}
if (charset)
}
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);
m_strcpy(d, len, d0);
p_delete(&charset);
p_delete(&d0);
* must be B or Q. Also, we don't require the encoded word to be
* separated by linear-white-space (section 5(1)).
*/
* 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;
+
+ 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] != '?')
- 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;
}
/* return length of linear white space */
}
/* 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;
+ for (p = s; p < s + n; p++) {
if (!strchr (" \t\r\n", *p)) {
if (!strchr (" \t\r\n", *p)) {
- len = (size_t) (p - s);
- 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 */
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;
{
const char *p = s + n - 1;
size_t len = n;
- 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;
- rfc2047_decode_word (d, p, dlen);
+ rfc2047_decode_word(d, dlen, p);
found_encoded = 1;
s = q;
n = m_strlen(d);
found_encoded = 1;
s = q;
n = m_strlen(d);