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));
}