From: Philip Hazel Date: Wed, 17 Nov 2004 15:21:10 +0000 (+0000) Subject: Respect the 75-character limit for "encoded words" when doing RFC 2047 X-Git-Tag: exim-4_50~101 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/14702f5b13007409b29615f2a2ad1b141a4b9561?hp=5cb8cbc6b514db2972dffadc30b3c7f2b7fc1dcb Respect the 75-character limit for "encoded words" when doing RFC 2047 encoding, and increase the buffer size for ${rfc2047: expansion. --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 4f49ef8e5..251de3fd4 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.29 2004/11/17 14:32:25 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.30 2004/11/17 15:21:10 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -122,6 +122,13 @@ Exim version 4.44 is then used to implement four new variables: $spool_space, $log_space, $spool_inodes, and $log_inodes. +32. The RFC2047 encoding function was originally intended for short strings + such as real names; it was not keeping to the 75-character limit for + encoded words that the RFC imposes. It now respects the limit, and + generates multiple encoded words if necessary. To be on the safe side, I + have increased the buffer size for the ${rfc2047: expansion operator from + 1024 to 2048 bytes. + Exim version 4.43 ----------------- diff --git a/src/src/expand.c b/src/src/expand.c index 0ca5b4cc2..916659f5e 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.4 2004/11/17 14:32:25 ph10 Exp $ */ +/* $Cambridge: exim/src/src/expand.c,v 1.5 2004/11/17 15:21:10 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -4083,7 +4083,7 @@ while (*s != 0) case EOP_RFC2047: { - uschar buffer[1024]; + uschar buffer[2048]; uschar *string = parse_quote_2047(sub, Ustrlen(sub), headers_charset, buffer, sizeof(buffer)); yield = string_cat(yield, &size, &ptr, string, Ustrlen(string)); diff --git a/src/src/parse.c b/src/src/parse.c index e42e0c8a8..e1a1a259c 100644 --- a/src/src/parse.c +++ b/src/src/parse.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/parse.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */ +/* $Cambridge: exim/src/src/parse.c,v 1.2 2004/11/17 15:21:10 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -847,6 +847,11 @@ If the only characters that strictly need quoting are spaces, we return the original string, unmodified. If a quoted string is too long for the buffer, it is truncated. (This shouldn't happen: this is normally handling short strings.) +Hmmph. As always, things get perverted for other uses. This function was +originally for the "phrase" part of addresses. Now it is being used for much +longer texts in ACLs and via the ${rfc2047: expansion item. This means we have +to check for overlong "encoded-word"s and split them. November 2004. + Arguments: string the string to quote - already checked to contain non-printing chars @@ -866,7 +871,8 @@ parse_quote_2047(uschar *string, int len, uschar *charset, uschar *buffer, int buffer_size) { uschar *s = string; -uschar *t; +uschar *p, *t; +int hlen; BOOL coded = FALSE; if (charset == NULL) charset = US"iso-8859-1"; @@ -876,11 +882,25 @@ if (charset == NULL) charset = US"iso-8859-1"; if (!string_format(buffer, buffer_size, "=?%s?Q?", charset)) return US"String too long"; -t = buffer + Ustrlen(buffer); +hlen = Ustrlen(buffer); +t = buffer + hlen; +p = buffer; + for (; len > 0; len--) { int ch = *s++; - if (t > buffer + buffer_size - 8) break; + if (t > buffer + buffer_size - hlen - 8) break; + + if (t - p > 70) + { + *t++ = '?'; + *t++ = '='; + *t++ = ' '; + p = t; + Ustrncpy(p, buffer, hlen); + t += hlen; + } + if (ch < 33 || ch > 126 || Ustrchr("?=()<>@,;:\\\".[]_", ch) != NULL) { @@ -893,7 +913,11 @@ for (; len > 0; len--) } else *t++ = ch; } -sprintf(CS t, "?="); + +*t++ = '?'; +*t++ = '='; +*t = 0; + return coded? buffer : string; }