Re: [1.5.9 bug] Mutt discards the \ character before a digit in "To:"
* Wed May 11 2005 Vincent Lefevre <vincent@xxxxxxxxxx>
> On 2005-05-10 13:32:47 -0400, Derek Martin wrote:
> > On Tue, May 10, 2005 at 06:20:11PM +0200, Vincent Lefevre wrote:
> > > With Mutt 1.5.9, if I try to send a mail to
> > >
> > > "blah\1" <a@xxx>
> > >
> > > (whether I write this from Mutt or from the editor), Mutt writes:
> > >
> > > To: blah1 <a@xxx>
> > >
> > > in the Compose window.
> >
> > I'm pretty sure that's expected behavior.
>
> Why would this be the expected behavior?
rfc822.c has rfc822_dequote_comment().
After experimenting it a little, I found it was a bad thing.
If we need to dequote personal names in headers,
we should do it while displaying it; Never while parsing it.
So I made a patch. (attached)
This patch also removes the quoting routine in
rfc822_write_address_single().
ie, We should quote a name by hand if the name contains
one or more of RFC822Specials[]. But who cares?
Well, someone may complain about it.
But please try these strings as "To:" header on the compose menu:
Foo \1 <foo@bar>
Foo \\1 <foo@bar>
Foo \\\1 <foo@bar>
"Foo \1 <foo@bar>"
"Foo \\1 <foo@bar>"
You will be surprised and say, "What an inconsistent behavior!"
So, I suggest this patch.
> > Another question would be why that's important... For most purposes
> > the real name portion of an e-mail address is ignored. Just
> > curious... The only reason I could come up with on my own is
> > filtering, but even then it's not hard to write a regex that matches
> > both "blah\1" and blah1.
>
> I don't think this is important, but this is a bug anyway, IMHO.
> I also wonder if it doesn't hide a more important bug.
The '\\' char represents a YEN mark with some Japanese fonts.
It must be important, it concerns money. ;)
For example, currently I can't send a message to "A \100-shop owner."
(Derek should know there are such shops in Japan. Those shops
sell various goods for 100 yen.)
--
tamo
Index: hdrline.c
===================================================================
RCS file: /home/roessler/cvs/mutt/hdrline.c,v
retrieving revision 3.14
diff -p -u -r3.14 hdrline.c
--- hdrline.c 12 Feb 2005 19:12:40 -0000 3.14
+++ hdrline.c 22 May 2005 11:06:04 -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)
@@ -492,7 +500,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':
@@ -587,10 +599,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;
@@ -616,15 +631,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.7
diff -p -u -r3.7 rfc822.c
--- rfc822.c 3 Feb 2005 17:01:44 -0000 3.7
+++ rfc822.c 22 May 2005 11:06:05 -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,8 +431,6 @@ 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);
}
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;
Index: sort.c
===================================================================
RCS file: /home/roessler/cvs/mutt/sort.c,v
retrieving revision 3.7
diff -p -u -r3.7 sort.c
--- sort.c 3 Feb 2005 17:01:44 -0000 3.7
+++ sort.c 22 May 2005 11:06:05 -0000
@@ -90,21 +90,34 @@ 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));
+ if (tmp)
+ {
+ size_t tmplen = mutt_strlen (tmp);
+ if (tmplen > 2 && *tmp == '"' && *(tmp + tmplen - 1) == '"')
+ {
+ char *rv = mutt_substrdup (tmp + 1, tmp + tmplen - 1);
+ FREE (&tmp);
+ return (rv);
+ }
+ return (tmp);
+ }
}
/* don't return NULL to avoid segfault when printing/comparing */
- return ("");
+ return (safe_strdup(""));
}
int compare_to (const void *a, const void *b)
@@ -117,6 +130,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 +146,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));
}