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

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



The following reply was made to PR mutt/2163; it has been noted by GNATS.

From: Vincent Lefevre <vincent@xxxxxxxxxx>
To: Mutt Developers <mutt-dev@xxxxxxxx>
Cc: bug-any@xxxxxxxxxxxxx
Subject: Re: mutt/2163: Mutt crashes on malformed "From:" header 
(quoted-printable)
Date: Sun, 15 Jan 2006 05:22:38 +0100

 --LQksG6bCIzRHxTLp
 Content-Type: text/plain; charset=iso-8859-1
 Content-Disposition: inline
 Content-Transfer-Encoding: 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.
 
 --=20
 Vincent Lef=E8vre <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
 
 --LQksG6bCIzRHxTLp
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="patch-1.5.11cvs.tamovl.namequot.1"
 
 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));
  }
 
 --LQksG6bCIzRHxTLp--