i've finally tracked this down:

nmh code assumes strcasecmp accepts NULL arguments.

for portability reasons sbr/strcasecmp.c defines str[n]casecmp functions 
which do accept NULL arguments.

/usr/include/string.h declares strcasecmp:

extern int strcasecmp (__const char *__s1, __const char *__s2)
     __THROW __attribute_pure__ __nonnull ((1, 2));

when compiling sbr/strcasecmp.c with -O2 gcc respects that nonnull 
declaration and eliminates the tests for NULL from the sbr/strcasecmp.c 
code.

this results in the (somewhat arbitrary) segfaults we've been seeing.

there are two solutions.  one is to compile with -O1 rather than -O2, 
which disables whatever optimization is doing this (i've tried -O2 
-fno-delete-null-pointer-checks but that still seems to delete the null 
tests... perhaps i should bug gcc too).

the other option is the patch below.  (i prefer this solution)

i'm also attaching a patch which is almost certainly necessary for 64-bit 
portability:  the difference of pointers is 64-bits yet the code is using 
pointer diffs in many places where int (32-bits) are required.

-dean

Index: nmh-1.2/h/nmh.h
===================================================================
--- nmh-1.2.orig/h/nmh.h        2007-05-21 23:41:43.577421877 -0700
+++ nmh-1.2/h/nmh.h     2007-05-21 23:41:57.149076687 -0700
@@ -41,6 +41,8 @@
 
 #if STDC_HEADERS || HAVE_STRING_H
 # include <string.h>
+# define strcasecmp my_strcasecmp
+# define strncasecmp my_strncasecmp
 /* An ANSI string.h and pre-ANSI memory.h might conflict.  */
 # if !STDC_HEADERS && HAVE_MEMORY_H
 #  include <memory.h>
Index: nmh-1.2/sbr/fmt_scan.c
===================================================================
--- nmh-1.2.orig/sbr/fmt_scan.c 2007-05-21 22:08:08.385987915 -0700
+++ nmh-1.2/sbr/fmt_scan.c      2007-05-21 22:09:51.159105255 -0700
@@ -255,7 +255,7 @@
            || !(cp = strchr(mbox += idx + strlen (key), '/')))
        return 0;
 
-    snprintf (buffer, buffer_len, "%*.*s", cp - mbox, cp - mbox, mbox);
+    snprintf (buffer, buffer_len, "%*.*s", (int)(cp - mbox), (int)(cp - mbox), 
mbox);
     return 1;
 }
 
Index: nmh-1.2/sbr/lock_file.c
===================================================================
--- nmh-1.2.orig/sbr/lock_file.c        2007-05-21 22:10:02.210795073 -0700
+++ nmh-1.2/sbr/lock_file.c     2007-05-21 22:10:12.638502370 -0700
@@ -493,7 +493,7 @@
     bplen += tmplen;
 #else
     if (cp != file) {
-       snprintf (bp, sizeof(li->curlock), "%.*s", cp - file, file);
+       snprintf (bp, sizeof(li->curlock), "%.*s", (int)(cp - file), file);
        tmplen = strlen (bp);
        bp    += tmplen;
        bplen += tmplen;
Index: nmh-1.2/sbr/m_backup.c
===================================================================
--- nmh-1.2.orig/sbr/m_backup.c 2007-05-21 22:10:29.590026473 -0700
+++ nmh-1.2/sbr/m_backup.c      2007-05-21 22:10:40.141730200 -0700
@@ -22,7 +22,7 @@
        snprintf(buffer, sizeof(buffer), "%s%s",
                BACKUP_PREFIX, cp);
     else
-       snprintf(buffer, sizeof(buffer), "%.*s%s%s", cp - file, file,
+       snprintf(buffer, sizeof(buffer), "%.*s%s%s", (int)(cp - file), file,
                BACKUP_PREFIX, cp);
 
     unlink(buffer);
Index: nmh-1.2/sbr/m_getfld.c
===================================================================
--- nmh-1.2.orig/sbr/m_getfld.c 2007-05-21 22:11:09.316921446 -0700
+++ nmh-1.2/sbr/m_getfld.c      2007-05-21 22:11:29.072375827 -0700
@@ -699,10 +699,10 @@
     if (cp) {
        /* return path for UUCP style addressing */
        dp = strchr (++cp, '\n');
-       snprintf (rp, rplen, "%.*s!%.*s\n", dp - cp, cp, bp - ap, ap);
+       snprintf (rp, rplen, "%.*s!%.*s\n", (int)(dp - cp), cp, (int)(bp - ap), 
ap);
     } else {
        /* return path for standard domain addressing */
-       snprintf (rp, rplen, "%.*s\n", bp - ap, ap);
+       snprintf (rp, rplen, "%.*s\n", (int)(bp - ap), ap);
     }
 
     /*
Index: nmh-1.2/sbr/m_scratch.c
===================================================================
--- nmh-1.2.orig/sbr/m_scratch.c        2007-05-21 22:11:38.268121797 -0700
+++ nmh-1.2/sbr/m_scratch.c     2007-05-21 22:11:45.303927411 -0700
@@ -33,7 +33,7 @@
     if ((cp = r1bindex (file, '/')) == file)
        strncpy (buffer, tmpfil, sizeof(buffer));
     else
-       snprintf (buffer, sizeof(buffer), "%.*s%s", cp - file, file, tmpfil);
+       snprintf (buffer, sizeof(buffer), "%.*s%s", (int)(cp - file), file, 
tmpfil);
     unlink (buffer);
 
     return buffer;
Index: nmh-1.2/sbr/mf.c
===================================================================
--- nmh-1.2.orig/sbr/mf.c       2007-05-21 22:12:24.410846588 -0700
+++ nmh-1.2/sbr/mf.c    2007-05-21 22:12:32.198631277 -0700
@@ -433,7 +433,7 @@
     while (isspace (*ap))
        ap++;
     if (cp)
-       sprintf (adr, "%.*s", cp - ap, ap);
+       sprintf (adr, "%.*s", (int)(cp - ap), ap);
     else
        strcpy (adr, ap);
     bp = adr + strlen (adr) - 1;
Index: nmh-1.2/sbr/path.c
===================================================================
--- nmh-1.2.orig/sbr/path.c     2007-05-21 22:11:56.443619600 -0700
+++ nmh-1.2/sbr/path.c  2007-05-21 22:12:16.211073263 -0700
@@ -85,7 +85,7 @@
        name += NCWD;
 
     if (strcmp (name, DOTDOT) == 0 || strcmp (name, PWD) == 0) {
-       snprintf (buffer, sizeof(buffer), "%.*s", cp - pwds, pwds);
+       snprintf (buffer, sizeof(buffer), "%.*s", (int)(cp - pwds), pwds);
        return getcpy (buffer);
     }
 
@@ -94,7 +94,7 @@
     else
        cp = ep;
 
-    snprintf (buffer, sizeof(buffer), "%.*s/%s", cp - pwds, pwds, name);
+    snprintf (buffer, sizeof(buffer), "%.*s/%s", (int)(cp - pwds), pwds, name);
     return getcpy (buffer);
 }
 
Index: nmh-1.2/uip/annosbr.c
===================================================================
--- nmh-1.2.orig/uip/annosbr.c  2007-05-21 22:12:49.394155779 -0700
+++ nmh-1.2/uip/annosbr.c       2007-05-21 22:13:00.665844024 -0700
@@ -384,7 +384,7 @@
                while (*cp && *cp++ != '\n')
                    continue;
                if (cp - sp)
-                   fprintf (tmp, "%s: %*.*s", comp, cp - sp, cp - sp, sp);
+                   fprintf (tmp, "%s: %*.*s", comp, (int)(cp - sp), (int)(cp - 
sp), sp);
            } while (*cp);
            if (cp[-1] != '\n' && cp != text)
                putc ('\n', tmp);
Index: nmh-1.2/uip/mhbuildsbr.c
===================================================================
--- nmh-1.2.orig/uip/mhbuildsbr.c       2007-05-21 22:13:25.841147532 -0700
+++ nmh-1.2/uip/mhbuildsbr.c    2007-05-21 22:13:44.884620511 -0700
@@ -4213,7 +4213,7 @@
            while (*cp)
                cp++;
            fprintf (stderr, "invalid MD5 digest (got %d octets)\n",
-                    cp - bp);
+                    (int)(cp - bp));
        }
 
        return NOTOK;
Index: nmh-1.2/uip/mhparse.c
===================================================================
--- nmh-1.2.orig/uip/mhparse.c  2007-05-21 22:13:55.160336074 -0700
+++ nmh-1.2/uip/mhparse.c       2007-05-21 22:14:01.720154472 -0700
@@ -2676,7 +2676,7 @@
            while (*cp)
                cp++;
            fprintf (stderr, "invalid MD5 digest (got %d octets)\n",
-                    cp - bp);
+                    (int)(cp - bp));
        }
 
        return NOTOK;
Index: nmh-1.2/uip/dropsbr.c
===================================================================
--- nmh-1.2.orig/uip/dropsbr.c  2007-05-21 22:14:17.055729856 -0700
+++ nmh-1.2/uip/dropsbr.c       2007-05-21 22:14:43.726991149 -0700
@@ -387,7 +387,7 @@
                            fp = strchr(ep + 1, '\n');
                        tp = dctime(dlocaltimenow());
                        snprintf (buffer, sizeof(buffer), "From %.*s  %s",
-                               fp - ep, ep, tp);
+                               (int)(fp - ep), ep, tp);
                    } else if (!strncmp (buffer, "X-Envelope-From:", 16)) {
                        /*
                         * Change the "X-Envelope-From:" field
@@ -499,10 +499,10 @@
     if ((dp = strchr(cp = r1bindex (file, '/'), '.')) == NULL)
        dp = cp + strlen (cp);
     if (cp == file)
-       snprintf (buffer, sizeof(buffer), ".%.*s%s", dp - cp, cp, ".map");
+       snprintf (buffer, sizeof(buffer), ".%.*s%s", (int)(dp - cp), cp, 
".map");
     else
        snprintf (buffer, sizeof(buffer), "%.*s.%.*s%s",
-               cp - file, file, dp - cp, cp, ".map");
+               (int)(cp - file), file, (int)(dp - cp), cp, ".map");
 
     return buffer;
 }
Index: nmh-1.2/uip/slocal.c
===================================================================
--- nmh-1.2.orig/uip/slocal.c   2007-05-21 22:14:51.174784819 -0700
+++ nmh-1.2/uip/slocal.c        2007-05-21 22:15:06.914348706 -0700
@@ -1372,11 +1372,11 @@
                    /* return path for UUCP style addressing */
                    ep = strchr(++hp, '\n');
                    snprintf (buffer, sizeof(buffer), "Return-Path: 
%.*s!%.*s\n",
-                       ep - hp, hp, cp - fp, fp);
+                       (int)(ep - hp), hp, (int)(cp - fp), fp);
                } else {
                    /* return path for standard domain addressing */
                    snprintf (buffer, sizeof(buffer), "Return-Path: %.*s\n",
-                       cp - fp, fp);
+                       (int)(cp - fp), fp);
                }
 
                /* Add Return-Path header to message */

Reply via email to