Package: mutt
Version: 1.5.13-3
Severity: normal
The following command line:
mutt 'mailto:[EMAIL
PROTECTED]&References=%3c153185.7884%40example.org%3e&[EMAIL PROTECTED]'
does not take into account the given "From" header. More generally,
any header (or body) that is put after the "References" header is
ignored. For example,
mutt 'mailto:[EMAIL
PROTECTED]@example.net'&References=%3c153185.7884%40example.org%3e&Subject=subj&[EMAIL
PROTECTED]
will take into account the "From" header, but neither the "Subject",
nor the "Reply-To".
That is because in this situation mutt uses the non-reentrant strtok
in a nested way. More precisely:
- "mailto:" URL parsing happens in function url_parse_mailto (file
url.c).
- that function calls strtok once with 'headers' as first argument
and then with 'NULL' as first argument, to continue advancing in
the same string.
- but if the header being parsed is "References" (that is 'tag' is
that string), then mutt_parse_rfc822_line (which finished the for
loop) (file parse.c) will call mutt_parse_references, which will in
turn call strtok() with a non-NULL first argument. (And then with
NULL argument until it returns NULL.)
- when the for loop in url_parse_mailto proceeds, the
strtok(NULL,...) call proceeds on the string passed by
mutt_parse_references, but it is already at its end, and returns
NULL, terminating that function.
The attached patch changes all calls to strtok to the reentrant
strtok_r, fixing that problem.
-- System Information:
Debian Release: lenny/sid
APT prefers unstable
APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.18-3-amd64 (SMP w/2 CPU cores)
Locale: LANG=fr_LU.UTF-8, LC_CTYPE=fr_LU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages mutt depends on:
ii exim4 4.67-1 metapackage to ease exim MTA (v4)
ii exim4-daemon-heavy [mail- 4.67-1 exim MTA (v4) daemon with extended
ii libc6 2.5-4 GNU C Library: Shared libraries
ii libdb4.4 4.4.20-8 Berkeley v4.4 Database Libraries [
ii libgnutls13 1.6.2-1 the GNU TLS library - runtime libr
ii libidn11 0.6.5-1 GNU libidn library, implementation
ii libncursesw5 5.5-5 Shared libraries for terminal hand
ii libsasl2-2 2.1.22.dfsg1-9 Authentication abstraction library
Versions of packages mutt recommends:
ii locales 2.5-4 GNU C Library: National Language (
ii mime-support 3.39-1 MIME files 'mime.types' & 'mailcap
-- no debconf information
diff --recursive -u mutt-1.5.13/attach.c mutt-1.5.13.strtok_safe/attach.c
--- mutt-1.5.13/attach.c 2006-02-21 09:04:59.000000000 +0100
+++ mutt-1.5.13.strtok_safe/attach.c 2007-05-26 20:09:42.474452218 +0200
@@ -301,13 +301,15 @@
if ((p = getenv ("MM_NOASK")) != NULL && *p)
{
+ char *strtok_saveptr = NULL;
+
if (mutt_strcmp (p, "1") == 0)
return (1);
strfcpy (tmp, p, sizeof (tmp));
p = tmp;
- while ((p = strtok (p, ",")) != NULL)
+ while ((p = strtok_r (p, ",", &strtok_saveptr)) != NULL)
{
if ((q = strrchr (p, '/')) != NULL)
{
diff --recursive -u mutt-1.5.13/crypt-gpgme.c
mutt-1.5.13.strtok_safe/crypt-gpgme.c
--- mutt-1.5.13/crypt-gpgme.c 2005-10-31 11:02:08.000000000 +0100
+++ mutt-1.5.13.strtok_safe/crypt-gpgme.c 2007-05-26 20:03:05.818425128
+0200
@@ -3478,8 +3478,8 @@
if ((scratch = safe_strdup (str)) == NULL)
return hints;
- for (t = strtok (scratch, " ,.:\"()<>\n"); t;
- t = strtok (NULL, " ,.:\"()<>\n"))
+ for (t = strtok_r (scratch, " ,.:\"()<>\n", &strtok_saveptr); t;
+ t = strtok_r (NULL, " ,.:\"()<>\n", &strtok_saveptr))
{
if (strlen (t) > 3)
hints = mutt_add_list (hints, t);
diff --recursive -u mutt-1.5.13/edit.c mutt-1.5.13.strtok_safe/edit.c
--- mutt-1.5.13/edit.c 2005-10-31 11:02:08.000000000 +0100
+++ mutt-1.5.13.strtok_safe/edit.c 2007-05-26 20:10:19.553071901 +0200
@@ -150,8 +150,9 @@
{
int offset, bytes, n;
char tmp[LONG_STRING];
+ char *strtok_saveptr = NULL;
- while ((msg = strtok (msg, " ,")) != NULL)
+ while ((msg = strtok_r (msg, " ,", &strtok_saveptr)) != NULL)
{
n = atoi (msg);
if (n > 0 && n <= Context->msgcount)
diff --recursive -u mutt-1.5.13/getdomain.c mutt-1.5.13.strtok_safe/getdomain.c
--- mutt-1.5.13/getdomain.c 2005-02-03 19:47:52.000000000 +0100
+++ mutt-1.5.13.strtok_safe/getdomain.c 2007-05-26 19:56:37.142921822 +0200
@@ -46,9 +46,11 @@
while (ISSPACE (*p)) p++;
if (mutt_strncmp ("domain", p, 6) == 0 || mutt_strncmp ("search", p, 6) ==
0)
{
+ char *strtok_saveptr = NULL;
+
p += 6;
- for (q = strtok (p, " \t\n"); q; q = strtok (NULL, " \t\n"))
+ for (q = strtok_r (p, " \t\n", &strtok_saveptr); q; q = strtok_r (NULL,
" \t\n", &strtok_saveptr))
if (strcmp (q, "."))
break;
diff --recursive -u mutt-1.5.13/mh.c mutt-1.5.13.strtok_safe/mh.c
--- mutt-1.5.13/mh.c 2006-08-11 11:07:12.000000000 +0200
+++ mutt-1.5.13.strtok_safe/mh.c 2007-05-26 20:00:02.217351584 +0200
@@ -159,7 +159,9 @@
while ((buff = mutt_read_line (buff, &sz, fp, &line)))
{
- if (!(t = strtok (buff, " \t:")))
+ char *strtok_saveptr = NULL;
+
+ if (!(t = strtok_r (buff, " \t:", &strtok_saveptr)))
continue;
if (!mutt_strcmp (t, MhUnseen))
@@ -171,7 +173,7 @@
else /* unknown sequence */
continue;
- while ((t = strtok (NULL, " \t:")))
+ while ((t = strtok_r (NULL, " \t:", &strtok_saveptr)))
{
mh_read_token (t, &first, &last);
for (; first <= last; first++)
diff --recursive -u mutt-1.5.13/parse.c mutt-1.5.13.strtok_safe/parse.c
--- mutt-1.5.13/parse.c 2006-04-28 21:48:32.000000000 +0200
+++ mutt-1.5.13.strtok_safe/parse.c 2007-05-26 20:07:12.007852591 +0200
@@ -94,8 +94,9 @@
LIST *t, *lst = NULL;
int m, n = 0;
char *o = NULL, *new, *at;
+ char *strtok_saveptr = NULL;
- while ((s = strtok (s, " \t;")) != NULL)
+ while ((s = strtok_r (s, " \t;", &strtok_saveptr)) != NULL)
{
/*
* some mail clients add other garbage besides message-ids, so do a quick
@@ -781,6 +782,7 @@
const char *ptz;
char tzstr[SHORT_STRING];
char scratch[SHORT_STRING];
+ char *strtok_saveptr = NULL;
/* Don't modify our argument. Fixed-size buffer is ok here since
* the date format imposes a natural limit.
@@ -797,7 +799,7 @@
memset (&tm, 0, sizeof (tm));
- while ((t = strtok (t, " \t")) != NULL)
+ while ((t = strtok_r (t, " \t", &strtok_saveptr)) != NULL)
{
switch (count)
{
@@ -877,7 +879,7 @@
/* ad hoc support for the European MET (now officially CET) TZ */
if (ascii_strcasecmp (t, "MET") == 0)
{
- if ((t = strtok (NULL, " \t")) != NULL)
+ if ((t = strtok_r (NULL, " \t", &strtok_saveptr)) != NULL)
{
if (!ascii_strcasecmp (t, "DST"))
zhours++;
@@ -1446,6 +1448,7 @@
ADDRESS *mutt_parse_adrlist (ADDRESS *p, const char *s)
{
const char *q;
+ char *strtok_saveptr = NULL;
/* check for a simple whitespace separated list of addresses */
if ((q = strpbrk (s, "\"<>():;,\\")) == NULL)
@@ -1455,7 +1458,7 @@
strfcpy (tmp, s, sizeof (tmp));
r = tmp;
- while ((r = strtok (r, " \t")) != NULL)
+ while ((r = strtok_r (r, " \t", &strtok_saveptr)) != NULL)
{
p = rfc822_parse_adrlist (p, r);
r = NULL;
diff --recursive -u mutt-1.5.13/pgpkey.c mutt-1.5.13.strtok_safe/pgpkey.c
--- mutt-1.5.13/pgpkey.c 2005-09-18 10:22:22.000000000 +0200
+++ mutt-1.5.13.strtok_safe/pgpkey.c 2007-05-26 19:57:17.781780847 +0200
@@ -788,12 +788,13 @@
{
char *scratch;
char *t;
+ char *strtok_saveptr = NULL;
if ((scratch = safe_strdup (str)) == NULL)
return hints;
- for (t = strtok (scratch, " ,.:\"()<>\n"); t;
- t = strtok (NULL, " ,.:\"()<>\n"))
+ for (t = strtok_r (scratch, " ,.:\"()<>\n" , &strtok_saveptr); t;
+ t = strtok_r (NULL, " ,.:\"()<>\n" , &strtok_saveptr))
{
if (strlen (t) > 3)
hints = mutt_add_list (hints, t);
diff --recursive -u mutt-1.5.13/postpone.c mutt-1.5.13.strtok_safe/postpone.c
--- mutt-1.5.13/postpone.c 2006-04-20 18:46:35.000000000 +0200
+++ mutt-1.5.13.strtok_safe/postpone.c 2007-05-26 20:03:55.965957091 +0200
@@ -376,13 +376,15 @@
else if (mutt_strncmp ("X-Mutt-Mix:", tmp->data, 11) == 0)
{
char *t;
+ char *strtok_saveptr = NULL;
+
mutt_free_list (&hdr->chain);
- t = strtok (tmp->data + 11, " \t\n");
+ t = strtok_r (tmp->data + 11, " \t\n", &strtok_saveptr);
while (t)
{
hdr->chain = mutt_add_list (hdr->chain, t);
- t = strtok (NULL, " \t\n");
+ t = strtok_r (NULL, " \t\n", &strtok_saveptr);
}
next = tmp->next;
diff --recursive -u mutt-1.5.13/query.c mutt-1.5.13.strtok_safe/query.c
--- mutt-1.5.13/query.c 2006-03-03 10:53:31.000000000 +0100
+++ mutt-1.5.13.strtok_safe/query.c 2007-05-26 19:59:18.762293301 +0200
@@ -103,7 +103,9 @@
*p = '\0';
while ((buf = mutt_read_line (buf, &buflen, fp, &dummy)) != NULL)
{
- if ((p = strtok(buf, "\t\n")))
+ char *strtok_saveptr = NULL;
+
+ if ((p = strtok_r(buf, "\t\n", &strtok_saveptr)))
{
if (first == NULL)
{
@@ -123,14 +125,14 @@
SecondColumn = l;
cur->addr = rfc822_parse_adrlist (cur->addr, p);
- p = strtok(NULL, "\t\n");
+ p = strtok_r(NULL, "\t\n", &strtok_saveptr);
if (p)
{
l = mutt_strwidth (p);
if (l > FirstColumn)
FirstColumn = l;
cur->name = safe_strdup (p);
- p = strtok(NULL, "\t\n");
+ p = strtok_r(NULL, "\t\n", &strtok_saveptr);
if (p)
{
cur->other = safe_strdup (p);
diff --recursive -u mutt-1.5.13/remailer.c mutt-1.5.13.strtok_safe/remailer.c
--- mutt-1.5.13/remailer.c 2006-05-18 20:44:29.000000000 +0200
+++ mutt-1.5.13.strtok_safe/remailer.c 2007-05-26 20:05:13.011430894 +0200
@@ -166,27 +166,28 @@
while (fgets (line, sizeof (line), fp))
{
+ char *strtok_saveptr = NULL;
p = mix_new_remailer ();
- if (!(t = strtok (line, " \t\n")))
+ if (!(t = strtok_r (line, " \t\n", &strtok_saveptr)))
goto problem;
p->shortname = safe_strdup (t);
- if (!(t = strtok (NULL, " \t\n")))
+ if (!(t = strtok_r (NULL, " \t\n", &strtok_saveptr)))
goto problem;
p->addr = safe_strdup (t);
- if (!(t = strtok (NULL, " \t\n")))
+ if (!(t = strtok_r (NULL, " \t\n", &strtok_saveptr)))
goto problem;
- if (!(t = strtok (NULL, " \t\n")))
+ if (!(t = strtok_r (NULL, " \t\n", &strtok_saveptr)))
goto problem;
p->ver = safe_strdup (t);
- if (!(t = strtok (NULL, " \t\n")))
+ if (!(t = strtok_r (NULL, " \t\n", &strtok_saveptr)))
goto problem;
p->caps = mix_get_caps (t);
diff --recursive -u mutt-1.5.13/sendlib.c mutt-1.5.13.strtok_safe/sendlib.c
--- mutt-1.5.13/sendlib.c 2006-07-18 20:16:24.000000000 +0200
+++ mutt-1.5.13.strtok_safe/sendlib.c 2007-05-26 20:02:04.897994046 +0200
@@ -954,6 +954,8 @@
if ((f = fopen (buf, "r")) != NULL)
{
+ char *strtok_saveptr = NULL;
+
while (fgets (buf, sizeof (buf) - 1, f) != NULL)
{
/* weed out any comments */
@@ -971,7 +973,7 @@
SKIPWS (p);
/* cycle through the file extensions */
- while ((p = strtok (p, " \t\n")))
+ while ((p = strtok_r (p, " \t\n", &strtok_saveptr)))
{
sze = mutt_strlen (p);
if ((sze > cur_sze) && (szf >= sze) &&
@@ -1925,10 +1927,11 @@
char **args = NULL;
size_t argslen = 0, argsmax = 0;
int i;
+ char *strtok_saveptr = NULL;
ps = s;
i = 0;
- while ((ps = strtok (ps, " ")))
+ while ((ps = strtok_r (ps, " ", &strtok_saveptr)))
{
if (argslen == argsmax)
safe_realloc (&args, sizeof (char *) * (argsmax += 5));
diff --recursive -u mutt-1.5.13/url.c mutt-1.5.13.strtok_safe/url.c
--- mutt-1.5.13/url.c 2005-09-18 10:22:22.000000000 +0200
+++ mutt-1.5.13.strtok_safe/url.c 2007-05-26 19:58:17.029950161 +0200
@@ -213,6 +213,7 @@
char *headers;
char *tag, *value;
char scratch[HUGE_STRING];
+ char *strtok_saveptr = NULL;
int taglen;
@@ -230,9 +231,9 @@
url_pct_decode (tmp);
e->to = rfc822_parse_adrlist (e->to, tmp);
- tag = headers ? strtok (headers, "&") : NULL;
+ tag = headers ? strtok_r (headers, "&", &strtok_saveptr) : NULL;
- for (; tag; tag = strtok (NULL, "&"))
+ for (; tag; tag = strtok_r (NULL, "&", &strtok_saveptr))
{
if ((value = strchr (tag, '=')))
*value++ = '\0';