<<< Date Index >>>     <<< Thread Index >>>

Re: mutt/2163: Mutt crashes on malformed "From:" header (quoted-printable)



On 2006-01-14 21:15:01 +0100, Vincent Lefevre wrote:
>  This is due to the namequot patch.

I've attached a fixed version of this namequot patch. The problem
was that mutt_get_name could return a null pointer.

-- 
Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA
Index: PATCHES
===================================================================
RCS file: /home/roessler/cvs/mutt/PATCHES,v
retrieving revision 3.6
diff -d -u -p -r3.6 PATCHES
--- PATCHES     9 Dec 2002 17:44:54 -0000       3.6
+++ PATCHES     15 Jan 2006 03:57:50 -0000
@@ -0,0 +1 @@
+patch-1.5.11cvs.tamovl.namequot.1
Index: copy.c
===================================================================
RCS file: /home/roessler/cvs/mutt/copy.c,v
retrieving revision 3.27
diff -d -u -p -r3.27 copy.c
--- copy.c      21 Oct 2005 04:35:37 -0000      3.27
+++ copy.c      15 Jan 2006 03:57:50 -0000
@@ -982,6 +982,7 @@ static int address_header_decode (char *
   if ((a = rfc822_parse_adrlist (a, s + l)) == NULL)
     return 0;
   
+  rfc822_dequotepersonal_adrlist (a);
   mutt_addrlist_to_local (a);
   rfc2047_decode_adrlist (a);
   
Index: hdrline.c
===================================================================
RCS file: /home/roessler/cvs/mutt/hdrline.c,v
retrieving revision 3.18
diff -d -u -p -r3.18 hdrline.c
--- hdrline.c   10 Jan 2006 19:15:21 -0000      3.18
+++ hdrline.c   15 Jan 2006 03:57:50 -0000
@@ -59,7 +59,11 @@ check_for_mailing_list (ADDRESS *adr, ch
     if (mutt_is_subscribed_list (adr))
     {
       if (pfx && buf && buflen)
-       snprintf (buf, buflen, "%s%s", pfx, mutt_get_name (adr));
+      {
+       char *name = mutt_get_name (adr);
+       snprintf (buf, buflen, "%s%s", pfx, name);
+       FREE (&name);
+      }
       return 1;
     }
   }
@@ -102,6 +106,7 @@ static int first_mailing_list (char *buf
 static void make_from (ENVELOPE *hdr, char *buf, size_t len, int do_lists)
 {
   int me;
+  char *name = NULL;
 
   me = mutt_addr_is_user (hdr->from);
 
@@ -114,13 +119,16 @@ static void make_from (ENVELOPE *hdr, ch
   }
 
   if (me && hdr->to)
-    snprintf (buf, len, "To %s", mutt_get_name (hdr->to));
+    snprintf (buf, len, "To %s", name = mutt_get_name (hdr->to));
   else if (me && hdr->cc)
-    snprintf (buf, len, "Cc %s", mutt_get_name (hdr->cc));
+    snprintf (buf, len, "Cc %s", name = mutt_get_name (hdr->cc));
   else if (hdr->from)
-    strfcpy (buf, mutt_get_name (hdr->from), len);
+    strfcpy (buf, name = mutt_get_name (hdr->from), len);
   else
     *buf = 0;
+
+  if (name)
+    FREE (&name);
 }
 
 static void make_from_addr (ENVELOPE *hdr, char *buf, size_t len, int do_lists)
@@ -493,7 +501,11 @@ hdr_format_str (char *dest,
       break;
 
     case 'n':
-      mutt_format_s (dest, destlen, prefix, mutt_get_name (hdr->env->from));
+      {
+       char *name = mutt_get_name (hdr->env->from);
+       mutt_format_s (dest, destlen, prefix, name);
+       FREE (&name);
+      }
       break;
 
     case 'N':
@@ -588,10 +600,13 @@ hdr_format_str (char *dest,
       if (!check_for_mailing_list (hdr->env->to, "To ", buf2, sizeof (buf2)) &&
          !check_for_mailing_list (hdr->env->cc, "Cc ", buf2, sizeof (buf2)))
       {
+       char *name = NULL;
        if (hdr->env->to)
-         snprintf (buf2, sizeof (buf2), "To %s", mutt_get_name (hdr->env->to));
+         snprintf (buf2, sizeof (buf2), "To %s", name = mutt_get_name 
(hdr->env->to));
        else if (hdr->env->cc)
-         snprintf (buf2, sizeof (buf2), "Cc %s", mutt_get_name (hdr->env->cc));
+         snprintf (buf2, sizeof (buf2), "Cc %s", name = mutt_get_name 
(hdr->env->cc));
+       if (name)
+         FREE (&name);
       }
       mutt_format_s (dest, destlen, prefix, buf2);
       break;
@@ -617,15 +632,22 @@ hdr_format_str (char *dest,
     case 'v':
       if (mutt_addr_is_user (hdr->env->from)) 
       {
+       char *name = NULL;
        if (hdr->env->to)
-         mutt_format_s (buf2, sizeof (buf2), prefix, mutt_get_name 
(hdr->env->to));
+         mutt_format_s (buf2, sizeof (buf2), prefix, name = mutt_get_name 
(hdr->env->to));
        else if (hdr->env->cc)
-         mutt_format_s (buf2, sizeof (buf2), prefix, mutt_get_name 
(hdr->env->cc));
+         mutt_format_s (buf2, sizeof (buf2), prefix, name = mutt_get_name 
(hdr->env->cc));
        else
          *buf2 = 0;
+       if (name)
+         FREE (&name);
       }
       else
-       mutt_format_s (buf2, sizeof (buf2), prefix, mutt_get_name 
(hdr->env->from));
+      {
+       char *name = mutt_get_name (hdr->env->from);
+       mutt_format_s (buf2, sizeof (buf2), prefix, name);
+       FREE (&name);
+      }
       if ((p = strpbrk (buf2, " %@")))
        *p = 0;
       mutt_format_s (dest, destlen, prefix, buf2);
Index: rfc822.c
===================================================================
RCS file: /home/roessler/cvs/mutt/rfc822.c,v
retrieving revision 3.9
diff -d -u -p -r3.9 rfc822.c
--- rfc822.c    17 Sep 2005 20:46:11 -0000      3.9
+++ rfc822.c    15 Jan 2006 03:57:50 -0000
@@ -60,28 +60,6 @@ const char *RFC822Errors[] = {
   "bad address spec"
 };
 
-void rfc822_dequote_comment (char *s)
-{
-  char *w = s;
-
-  for (; *s; s++)
-  {
-    if (*s == '\\')
-    {
-      if (!*++s)
-       break; /* error? */
-      *w++ = *s;
-    }
-    else if (*s != '\"')
-    {
-      if (w != s)
-       *w = *s;
-      w++;
-    }
-  }
-  *w = 0;
-}
-
 void rfc822_free_address (ADDRESS **p)
 {
   ADDRESS *t;
@@ -119,6 +97,8 @@ parse_comment (const char *s,
     }
     else if (*s == '\\')
     {
+      if (*commentlen < commentmax)
+       comment[(*commentlen)++] = *s;
       if (!*++s)
        break;
     }
@@ -153,8 +133,8 @@ parse_quote (const char *s, char *token,
       if (!*++s)
        break;
 
-      if (*tokenlen < tokenmax)
-       token[*tokenlen] = *s;
+      if (*tokenlen + 1 < tokenmax)
+       token[++(*tokenlen)] = *s;
     }
     (*tokenlen)++;
     s++;
@@ -451,9 +431,7 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *
       {
        if (cur->personal)
          FREE (&cur->personal);
-       /* if we get something like "Michael R. Elkins" remove the quotes */
-       rfc822_dequote_comment (phrase);
-       cur->personal = safe_strdup (phrase);
+         cur->personal = safe_strdup (phrase);
       }
       if ((ps = parse_route_addr (s + 1, comment, &commentlen, sizeof 
(comment) - 1, cur)) == NULL)
       {
@@ -531,11 +509,6 @@ rfc822_cat (char *buf, size_t buflen, co
     *pc++ = '"';
     for (; *value && tmplen > 1; value++)
     {
-      if (*value == '\\' || *value == '"')
-      {
-       *pc++ = '\\';
-       tmplen--;
-      }
       *pc++ = *value;
       tmplen--;
     }
@@ -582,40 +555,12 @@ void rfc822_write_address_single (char *
 
   if (addr->personal)
   {
-    if (strpbrk (addr->personal, RFC822Specials))
-    {
-      if (!buflen)
-       goto done;
-      *pbuf++ = '"';
-      buflen--;
-      for (pc = addr->personal; *pc && buflen > 0; pc++)
-      {
-       if (*pc == '"' || *pc == '\\')
-       {
-         if (!buflen)
-           goto done;
-         *pbuf++ = '\\';
-         buflen--;
-       }
-       if (!buflen)
-         goto done;
-       *pbuf++ = *pc;
-       buflen--;
-      }
-      if (!buflen)
-       goto done;
-      *pbuf++ = '"';
-      buflen--;
-    }
-    else
-    {
-      if (!buflen)
-       goto done;
-      strfcpy (pbuf, addr->personal, buflen);
-      len = mutt_strlen (pbuf);
-      pbuf += len;
-      buflen -= len;
-    }
+    if (!buflen)
+      goto done;
+    strfcpy (pbuf, addr->personal, buflen);
+    len = mutt_strlen (pbuf);
+    pbuf += len;
+    buflen -= len;
 
     if (!buflen)
       goto done;
@@ -791,6 +736,41 @@ ADDRESS *rfc822_append (ADDRESS **a, ADD
   return tmp;
 }
 
+/* dequote personal name */
+char *rfc822_dequote_personal (char **s)
+{
+  if (*s && **s)
+  {
+    size_t slen = mutt_strlen (*s);
+    char *r = safe_malloc (slen + 1);
+    char *p = *s, *q = r;
+    if (slen > 2 && **s == '"' && *(*s + slen - 1) == '"')
+    {
+      p++;
+      slen--;
+    }
+    for (; p < *s + slen; p++)
+    {
+      if (*p == '\\')
+        *q++ = *++p;
+      else
+        *q++ = *p;
+    }
+    *q = 0;
+    FREE (s);
+    *s = r;
+  }
+  return (*s);
+}
+
+/* dequote personal names in adrlist */
+void rfc822_dequotepersonal_adrlist (ADDRESS *a)
+{
+  ADDRESS *cur = a;
+  for (; cur; cur = cur->next)
+    rfc822_dequote_personal (&cur->personal);
+}
+
 #ifdef TESTING
 int safe_free (void **p)
 {
Index: rfc822.h
===================================================================
RCS file: /home/roessler/cvs/mutt/rfc822.h,v
retrieving revision 3.5
diff -d -u -p -r3.5 rfc822.h
--- rfc822.h    17 Sep 2005 20:46:11 -0000      3.5
+++ rfc822.h    15 Jan 2006 03:57:50 -0000
@@ -52,6 +52,8 @@ void rfc822_write_address (char *, size_
 void rfc822_write_address_single (char *, size_t, ADDRESS *, int);
 void rfc822_free_address (ADDRESS **addr);
 void rfc822_cat (char *, size_t, const char *, const char *);
+char *rfc822_dequote_personal (char **);
+void rfc822_dequotepersonal_adrlist (ADDRESS *);
 
 extern int RFC822Error;
 extern const char *RFC822Errors[];
Index: sort.c
===================================================================
RCS file: /home/roessler/cvs/mutt/sort.c,v
retrieving revision 3.9
diff -d -u -p -r3.9 sort.c
--- sort.c      17 Sep 2005 20:46:11 -0000      3.9
+++ sort.c      15 Jan 2006 03:57:51 -0000
@@ -90,21 +90,28 @@ int compare_subject (const void *a, cons
   return (SORTCODE (rc));
 }
 
+/* needs freeing */
 const char *mutt_get_name (ADDRESS *a)
 {
   ADDRESS *ali;
+  char *tmp = NULL;
 
   if (a)
   {
     if (option (OPTREVALIAS) && (ali = alias_reverse_lookup (a)) && 
ali->personal)
-      return ali->personal;
+      tmp = safe_strdup (ali->personal);
     else if (a->personal)
-      return a->personal;
+      tmp = safe_strdup (a->personal);
     else if (a->mailbox)
-      return (mutt_addr_for_display (a));
+      tmp = safe_strdup (mutt_addr_for_display (a));
+    tmp = rfc822_dequote_personal (&tmp);
+    if (tmp)
+      return tmp;
   }
   /* don't return NULL to avoid segfault when printing/comparing */
-  return ("");
+  tmp = safe_malloc (1);
+  *tmp = '\0';
+  return tmp;
 }
 
 int compare_to (const void *a, const void *b)
@@ -117,6 +124,8 @@ int compare_to (const void *a, const voi
   fa = mutt_get_name ((*ppa)->env->to);
   fb = mutt_get_name ((*ppb)->env->to);
   result = mutt_strcasecmp (fa, fb);
+  FREE (&fa);
+  FREE (&fb);
   AUXSORT(result,a,b);
   return (SORTCODE (result));
 }
@@ -131,6 +140,8 @@ int compare_from (const void *a, const v
   fa = mutt_get_name ((*ppa)->env->from);
   fb = mutt_get_name ((*ppb)->env->from);
   result = mutt_strcasecmp (fa, fb);
+  FREE (&fa);
+  FREE (&fb);
   AUXSORT(result,a,b);
   return (SORTCODE (result));
 }