]> granicus.if.org Git - mutt/commitdiff
Fix some RFC2047 encoding bugs.
authorThomas Roessler <roessler@does-not-exist.org>
Fri, 15 Sep 2000 09:19:29 +0000 (09:19 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Fri, 15 Sep 2000 09:19:29 +0000 (09:19 +0000)
rfc2047.c
rfc2047.h
sendlib.c

index 3dde035495f2f8194763bebc74e519f18d4059dd..8bf32c8d52dc8e05147f4d5375214b262b4593fd 100644 (file)
--- a/rfc2047.c
+++ b/rfc2047.c
@@ -41,7 +41,9 @@
 #define ENCWORD_LEN_MAX 75
 #define ENCWORD_LEN_MIN 9 /* strlen ("=?.?.?.?=") */
 
-#define HSPACE(x) ((x) == ' ' || (x) == '\t')
+#define HSPACE(x) ((x) == '\0' || (x) == ' ' || (x) == '\t')
+
+extern char RFC822Specials[];
 
 typedef size_t (*encoder_t) (char *, const char *, size_t,
                             const char *);
@@ -348,12 +350,13 @@ static size_t choose_block (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 **e, size_t *elen, char *specials)
 {
   int ret = 0;
   char *buf;
   size_t bufpos, buflen;
   char *u, *t0, *t1, *t;
+  char *s0, *s1;
   size_t ulen, r, n, wlen;
   encoder_t encoder;
   char *tocode1 = 0;
@@ -363,23 +366,41 @@ static int rfc2047_encode (const char *d, size_t dlen, int col,
   /* Try to convert to UTF-8. */
   if (convert_string (d, dlen, fromcode, icode, &u, &ulen))
   {
-    ret = 1, icode = 0;
-    u = safe_malloc (ulen = dlen), memcpy (u, d, dlen);
+    ret = 1; 
+    icode = 0;
+    u = safe_malloc ((ulen = dlen) + 1);
+    memcpy (u, d, dlen);
+    u[ulen] = 0;
   }
 
   /* Find earliest and latest things we must encode. */
-  t0 = t1 = 0;
-  for (t = u; t < u + ulen - 1; t++)
-    if ((*t & 0x80) ||
+  s0 = s1 = t0 = t1 = 0;
+  for (t = u; t < u + ulen; t++)
+  {
+    if ((*t & 0x80) || 
        (*t == '=' && t[1] == '?' && (t == u || HSPACE(*(t-1)))))
-      t0 = t0 ? t0 : t, t1 = t;
-  if (t == u + ulen - 1 && (*t & 0x80))
-    t0 = t0 ? t0 : t, t1 = t;
+    {
+      if (!t0) t0 = t;
+      t1 = t;
+    }
+    else if (specials && strchr (specials, *t))
+    {
+      if (!s0) s0 = t;
+      s1 = t;
+    }
+  }
+
+  /* If we have something to encode, include RFC822 specials */
+  if (t0 && s0 && s0 < t0)
+    t0 = s0;
+  if (t1 && s1 && s1 > t1)
+    t1 = s1;
 
   if (!t0)
   {
     /* No encoding is required. */
-    *e = u, *elen = ulen;
+    *e = u;
+    *elen = ulen;
     return ret;
   }
 
@@ -399,8 +420,9 @@ static int rfc2047_encode (const char *d, size_t dlen, int col,
   
   /* Adjust t0 for maximum length of line. */
   t = u + (ENCWORD_LEN_MAX + 1) - col - ENCWORD_LEN_MIN;
-  t = t > u ? t : u;
-  t0 = t < t0 ? t : t0;
+  if (t < u)  t = u;
+  if (t < t0) t0 = t;
+  
 
   /* Adjust t0 until we can encode a character after a space. */
   for (; t0 > u; t0--)
@@ -498,7 +520,7 @@ static int rfc2047_encode (const char *d, size_t dlen, int col,
   return ret;
 }
 
-void rfc2047_encode_string (char **pd)
+void _rfc2047_encode_string (char **pd, int encode_specials, int col)
 {
   char *e;
   size_t elen;
@@ -511,10 +533,9 @@ void rfc2047_encode_string (char **pd)
   if (!charsets || !*charsets)
     charsets = "UTF-8";
 
-  /* Pretend that we are starting in column 32, thus allowing for a
-     field-name with up to 30 characters. */
-  rfc2047_encode (*pd, strlen (*pd), 32,
-                 Charset, charsets, &e, &elen);
+  rfc2047_encode (*pd, strlen (*pd), col,
+                 Charset, charsets, &e, &elen,
+                 encode_specials ? RFC822Specials : NULL);
 
   safe_realloc ((void **) &e, elen + 1);
   e[elen] = '\0';
@@ -522,17 +543,18 @@ void rfc2047_encode_string (char **pd)
   *pd = e;
 }
 
-void rfc2047_encode_adrlist (ADDRESS *addr)
+void rfc2047_encode_adrlist (ADDRESS *addr, const char *tag)
 {
   ADDRESS *ptr = addr;
-
+  int col = tag ? strlen (tag) + 2 : 32;
+  
   while (ptr)
   {
     if (ptr->personal)
-      rfc2047_encode_string (&ptr->personal);
+      _rfc2047_encode_string (&ptr->personal, 1, col);
 #ifdef EXACT_ADDRESS
     if (ptr->val)
-      rfc2047_encode_string (&ptr->val);
+      _rfc2047_encode_string (&ptr->val, 1, col);
 #endif
     ptr = ptr->next;
   }
index 2f6bd8877f0d004628ea693bdacdc23701f37a8c..7b4a7eafbf3b641e875b5a5eee33dd63dcb826b5 100644 (file)
--- a/rfc2047.h
+++ b/rfc2047.h
 char *mutt_choose_charset (const char *fromcode, const char *charsets,
                      char *u, size_t ulen, char **d, size_t *dlen);
 
-void rfc2047_encode_string (char **);
-void rfc2047_encode_adrlist (ADDRESS *);
+void _rfc2047_encode_string (char **, int, int);
+void rfc2047_encode_adrlist (ADDRESS *, const char *);
+
+#define rfc2047_encode_string(a) _rfc2047_encode_string (a, 0, 32);
 
 void rfc2047_decode (char **);
 void rfc2047_decode_adrlist (ADDRESS *);
index c3fb733cc610d6352baadf7c2b0721a9fb630fc5..1af81aa880f0f7d1c45080ff06e3612369716492 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -2072,11 +2072,11 @@ void mutt_prepare_envelope (ENVELOPE *env, int final)
   }
 
   /* Take care of 8-bit => 7-bit conversion. */
-  rfc2047_encode_adrlist (env->to);
-  rfc2047_encode_adrlist (env->cc);
-  rfc2047_encode_adrlist (env->from);
-  rfc2047_encode_adrlist (env->mail_followup_to);
-  rfc2047_encode_adrlist (env->reply_to);
+  rfc2047_encode_adrlist (env->to, "To");
+  rfc2047_encode_adrlist (env->cc, "Cc");
+  rfc2047_encode_adrlist (env->from, "From");
+  rfc2047_encode_adrlist (env->mail_followup_to, "Mail-Followup-To");
+  rfc2047_encode_adrlist (env->reply_to, "Reply-To");
 
   if (env->subject)
   {
@@ -2161,7 +2161,7 @@ void mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to)
   if (fqdn)
     rfc822_qualify (from, fqdn);
 
-  rfc2047_encode_adrlist (from);
+  rfc2047_encode_adrlist (from, "Resent-From");
   
   rfc822_write_address (resent_from, sizeof (resent_from), from);