Respect the 75-character limit for "encoded words" when doing RFC 2047
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 17 Nov 2004 15:21:10 +0000 (15:21 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 17 Nov 2004 15:21:10 +0000 (15:21 +0000)
encoding, and increase the buffer size for ${rfc2047: expansion.

doc/doc-txt/ChangeLog
src/src/expand.c
src/src/parse.c

index 4f49ef8e5598561b0c57668643c45a649cb231bd..251de3fd4b4221f8c2ee8ac69304e850fec10067 100644 (file)
@@ -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
 -----------------
index 0ca5b4cc2b0eb917621433f623a9275207bebdcb..916659f5eb0a9fa3dc6d8f572d2e5cbf72d4cee0 100644 (file)
@@ -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));
index e42e0c8a8e99e3c4388df389ed1b3f5dfe98286b..e1a1a259cc546ee1726737b609d616579a55f89d 100644 (file)
@@ -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;
 }