Crashes with the "indent" patch on Mutt v1.5.17
Hi all,
Quite a while ago, Jimmy Mäkelä wrote an "indent" patch for Mutt that I
have been using for a long time. However, when I applied it to Mutt
v1.5.17, it caused a crash. I've attached the patch for reference.
Note that I compiled with gcc v3.3.2 on a Sun Solaris 8 system.
I'm hoping there may be someone out there that is familiar with the
patch, or just willing to help with the debug.
I last applied the indent-patch to mutt 1.5.15 . I didn't try 1.5.16;
but when applied to 1.5.17 mutt crashes when I try to reply to a
message. Note that there are no other patches applied. Here is the
backtrace from the core file:
------------------------------ Delimiter BEGIN --------------------------------
core 'core' of 6419: ./mutt
0007f02c mutt_FormatString (ffbe8ba8, 7f, 0, 69, 2e004, 13f078) + c0
0002e4f4 _mutt_copy_message (e30b8, e30a8, 13ec00, 13ec60, 167, 86) + 68
0002ea98 mutt_copy_message (ffffffff, 127c58, 13ec00, 167, 86, b0) + 38
0006e860 include_reply (0, 13ec00, e30b8, e2af0, e3000, e3400) + a0
0006f328 generate_body (ffffffff, 1eaf88, 1, 127c58, 13ec00, ffffff8a) + 25c
00070ccc ci_send_message (0, 0, 0, 127c58, 1, 0) + 1344
0003547c mutt_index_menu (1, 0, 0, 0, 4, 0) + 3ffc
0004ba18 main (1, ffbea6ec, 0, b9000, 0, e3400) + b5c
0001de8c _start (0, 0, 0, 0, 0, 0) + 5c
------------------------------- Delimiter END ---------------------------------
And below is a gdb session where I set a breakpoint close to the point of
failure and then single stepped the code until the crash occurred.
However, the execution flow seems weird so I'm not sure how much value
to put on the trace. Note that one change I had to make in the patch
is that mutt_FormatString() now has an extra arg ('col') and so I pass
in a zero for that arg.
And now, here is the gdb log:
------------------------------ Delimiter BEGIN --------------------------------
(gdb) list muttlib.c:1000
995 const char *src, /* template string */
996 format_t *callback, /* callback for
processing */
997 unsigned long data, /* callback data */
998 format_flag flags) /* callback flags */
999 {
1000 char prefix[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch;
1001 char ifstring[SHORT_STRING], elsestring[SHORT_STRING];
1002 size_t wlen, count, len, wid;
1003 pid_t pid;
1004 FILE *filter;
(gdb) b 1000
Breakpoint 1 at 0x7ef7c: file muttlib.c, line 1000.
(gdb) c
Breakpoint 1, mutt_FormatString (dest=0xffbe8ba0 "", destlen=256, col=0,
src=0xfde08 "Hi %v,\n\nOn %[%a, %b %d, %Y at %I:%M %p %Z], %n wrote:",
callback=0x45e4c <hdr_format_str>, data=4290677536, flags=0) at muttlib.c:1000
1000 char prefix[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch;
(gdb) c
Breakpoint 1, mutt_FormatString (dest=0xffbe8ba8 "\n\nOn Fri, Sep 22, 2006 at
10:43 AM PDT, Mun Johl wrote:", destlen=128, col=0, src=0xfc9a0 "%i> ",
callback=0x2e004 <indent_format_str>, data=1306936, flags=0) at muttlib.c:1000
1000 char prefix[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch;
(gdb) n
1010 wlen = (flags & M_FORMAT_ARROWCURSOR && option (OPTARROWCURSOR)) ? 3
: 0;
(gdb)
1011 col += wlen;
(gdb)
1013 if ((flags & M_FORMAT_NOFILTER) == 0)
(gdb)
1011 col += wlen;
(gdb)
1013 if ((flags & M_FORMAT_NOFILTER) == 0)
(gdb)
1018 n = mutt_strlen(src);
(gdb)
1019 if (n > 1 && src[n-1] == '|')
(gdb)
1126 if (*src == '%')
(gdb)
1128 if (*++src == '%')
(gdb)
1137 if (*src == '?')
(gdb)
1144 flags &= ~M_FORMAT_OPTIONAL;
(gdb)
1149 while (count < sizeof (prefix) &&
(gdb)
1147 cp = prefix;
(gdb)
1148 count = 0;
(gdb)
1149 while (count < sizeof (prefix) &&
(gdb)
1158 if (!*src)
(gdb)
1163 if (flags & M_FORMAT_OPTIONAL)
(gdb)
1198 if (ch == '>' || ch == '*')
(gdb)
1253 else if (ch == '|')
(gdb)
1283 while (ch == '_' || ch == ':')
(gdb)
1280 short tolower = 0;
(gdb)
1283 while (ch == '_' || ch == ':')
(gdb)
1281 short nodots = 0;
(gdb)
1283 while (ch == '_' || ch == ':')
(gdb)
1294 src = callback (buf, sizeof (buf), col, ch, src, prefix,
ifstring, elsestring, data, flags);
(gdb)
1296 if (tolower)
(gdb)
1298 if (nodots)
(gdb)
1306 if ((len = mutt_strlen (buf)) + wlen > destlen)
(gdb)
1309 memcpy (wptr, buf, len);
(gdb)
1312 col += mutt_strwidth (buf);
(gdb)
1310 wptr += len;
(gdb)
1312 col += mutt_strwidth (buf);
(gdb)
1311 wlen += len;
(gdb)
1312 col += mutt_strwidth (buf);
(gdb)
1362 wlen = destlen;
(gdb)
procfs: couldn't stop process 6462: wait returned -1
(gdb)
------------------------------- Delimiter END ---------------------------------
Thanks in advance.
Best regards,
--
Mun
Index: copy.c
===================================================================
RCS file: /home/roessler/cvs/mutt/copy.c,v
retrieving revision 2.20
diff -u -u -r2.20 copy.c
--- copy.c 2001/01/15 10:40:50 2.20
+++ copy.c 2001/02/07 13:05:50
@@ -406,6 +406,88 @@
return dellines;
}
+static const char *
+indent_format_str (char *dest, size_t destlen, char op, const char *src,
+ const char *fmt, const char *ifstring, const char
*elsestring,
+ unsigned long data, format_flag flags)
+{
+ char tmp[SHORT_STRING], buf[SHORT_STRING], *pt;
+ ADDRESS *adr = (ADDRESS *) data;
+
+ strncpy (buf, NONULL (adr->personal), sizeof (buf));
+
+ switch (op)
+ {
+ case 'f':
+ snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+ pt = buf;
+
+ /* Extract the first name, save it in buf. */
+ SKIPWS (pt);
+ while (*pt && !isspace (*pt))
+ pt++;
+ *pt = 0;
+
+ snprintf (dest, destlen, tmp, buf);
+ break;
+
+ case 'l':
+ snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+ pt = buf + strlen (buf);
+
+ /* Skip white-space backwards. */
+ while ((pt != buf) && isspace (*pt))
+ pt--;
+ *pt = 0;
+
+ /* Extract the last name. save a pointer to it in pt. */
+ while ((pt != buf) && (*(pt - 1) != ' '))
+ pt--;
+
+ snprintf (dest, destlen, tmp, pt);
+ break;
+
+ case 'i':
+ snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+
+ pt = NONULL (adr->personal);
+ SKIPWS (pt);
+
+ /* Save all initials in buf. */
+ buf[0] = 0;
+ while (*pt)
+ {
+ if (isalpha (*pt))
+ strncat (buf, pt, 1);
+
+ /* Skip the rest of the characters of the current name. */
+ while (*pt && !isspace (*pt))
+ pt++;
+
+ if (*pt)
+ SKIPWS (pt);
+ }
+
+ snprintf (dest, destlen, tmp, buf);
+ break;
+
+ case 'u':
+ snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+
+ pt = strncpy (buf, NONULL (adr->mailbox), sizeof (buf));
+ SKIPWS (pt);
+
+ /* Extract the username. */
+ while (*pt && *pt != '@')
+ pt++;
+ *pt = 0;
+
+ snprintf (dest, destlen, tmp, buf);
+ break;
+ }
+ return (src);
+}
+
/* make a copy of a message
*
* fpout where to write output
@@ -432,7 +514,7 @@
long new_offset = -1;
if (flags & M_CM_PREFIX)
- _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr,
0);
+ mutt_FormatString (prefix, sizeof (prefix), NONULL (Prefix),
indent_format_str, (unsigned long) hdr->env->from, 0);
if ((flags & M_CM_NOHEADER) == 0)
{