Bug #20028 (Debian bug 399271): fix code assuming that pointer
[mmh] / sbr / mf.c
index cb3e6e4..ac04c29 100644 (file)
--- a/sbr/mf.c
+++ b/sbr/mf.c
 #include <h/mf.h>
 #include <ctype.h>
 #include <stdio.h>
+#include <h/utils.h>
 
 /*
  * static prototypes
  */
 static char *getcpy (char *);
-static char *add (char *, char *);
-static void compress (char *, char *);
+static void compress (char *, unsigned char *);
 static int isat (char *);
 static int parse_address (void);
 static int phrase (char *);
@@ -42,26 +42,12 @@ getcpy (char *s)
        for(;;)
            pause();
     }
-    if ((p = malloc ((size_t) (strlen (s) + 2))))
-       strcpy (p, s);
+    p = mh_xmalloc ((size_t) (strlen (s) + 2));
+    strcpy (p, s);
     return p;
 }
 
 
-static char *
-add (char *s1, char *s2)
-{
-    register char *p;
-
-    if (!s2)
-       return getcpy (s1);
-
-    if ((p = malloc ((size_t) (strlen (s1) + strlen (s2) + 2))))
-       sprintf (p, "%s%s", s2, s1);
-    free (s2);
-    return p;
-}
-
 int
 isfrom(char *string)
 {
@@ -71,7 +57,7 @@ isfrom(char *string)
 
 
 int
-lequal (char *a, char *b)
+lequal (unsigned char *a, unsigned char *b)
 {
     for (; *a; a++, b++)
        if (*b == 0)
@@ -147,7 +133,8 @@ seekadrx (char *addrs)
 struct adrx *
 uucpadrx (char *addrs)
 {
-    register char *cp, *wp, *xp, *yp, *zp;
+    register unsigned char *cp, *wp, *xp, *yp;
+    register char *zp;
     register struct adrx *adrxp = &adrxs1;
 
     if (vp == NULL) {
@@ -220,9 +207,10 @@ uucpadrx (char *addrs)
 
 
 static void
-compress (char *fp, char *tp)
+compress (char *fp, unsigned char *tp)
 {
-    register char c, *cp;
+    register char c;
+    register unsigned char *cp;
 
     for (c = ' ', cp = tp; (*tp = *fp++) != 0;)
        if (isspace (*tp)) {
@@ -347,8 +335,8 @@ static int ingrp = 0;
 static int last_lex = LX_END;
 
 static char *dp = NULL;
-static char *cp = NULL;
-static char *ap = NULL;
+static unsigned char *cp = NULL;
+static unsigned char *ap = NULL;
 static char *pers = NULL;
 static char *mbox = NULL;
 static char *host = NULL;
@@ -433,7 +421,7 @@ getadrx (char *addrs)
     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;
@@ -771,8 +759,13 @@ route (char *buffer)
 static int
 my_lex (char *buffer)
 {
+    /* buffer should be at least BUFSIZ bytes long */
     int i, gotat = 0;
-    register char c, *bp;
+    register unsigned char c;
+    register char *bp;
+
+/* Add C to the buffer bp. After use of this macro *bp is guaranteed to be within the buffer. */
+#define ADDCHR(C) do { *bp++ = (C); if ((bp - buffer) == (BUFSIZ-1)) goto my_lex_buffull; } while (0)
 
     bp = buffer;
     *bp = 0;
@@ -788,27 +781,28 @@ my_lex (char *buffer)
        return (last_lex = LX_END);
     }
 
-    if (c == '(')
-       for (*bp++ = c, i = 0;;)
+    if (c == '(') {
+       ADDCHR(c);
+       for (i = 0;;)
            switch (c = *cp++) {
                case 0: 
                    cp = NULL;
                    return (last_lex = LX_ERR);
                case QUOTE: 
-                   *bp++ = c;
+                   ADDCHR(c);
                    if ((c = *cp++) == 0) {
                        cp = NULL;
                        return (last_lex = LX_ERR);
                    }
-                   *bp++ = c;
+                   ADDCHR(c);
                    continue;
                case '(': 
                    i++;
                default: 
-                   *bp++ = c;
+                   ADDCHR(c);
                    continue;
                case ')': 
-                   *bp++ = c;
+                   ADDCHR(c);
                    if (--i < 0) {
                        *bp = 0;
                        note = note ? add (buffer, add (" ", note))
@@ -816,50 +810,55 @@ my_lex (char *buffer)
                        return my_lex (buffer);
                    }
            }
+    }
 
-    if (c == '"')
-       for (*bp++ = c;;)
+    if (c == '"') {
+       ADDCHR(c);
+       for (;;)
            switch (c = *cp++) {
                case 0: 
                    cp = NULL;
                    return (last_lex = LX_ERR);
                case QUOTE: 
-                   *bp++ = c;
+                   ADDCHR(c);
                    if ((c = *cp++) == 0) {
                        cp = NULL;
                        return (last_lex = LX_ERR);
                    }
                default: 
-                   *bp++ = c;
+                   ADDCHR(c);
                    continue;
                case '"': 
-                   *bp++ = c;
+                   ADDCHR(c);
                    *bp = 0;
                    return (last_lex = LX_QSTR);
            }
-
-    if (c == '[')
-       for (*bp++ = c;;)
+    }
+    
+    if (c == '[') {
+       ADDCHR(c);
+       for (;;)
            switch (c = *cp++) {
                case 0: 
                    cp = NULL;
                    return (last_lex = LX_ERR);
                case QUOTE: 
-                   *bp++ = c;
+                   ADDCHR(c);
                    if ((c = *cp++) == 0) {
                        cp = NULL;
                        return (last_lex = LX_ERR);
                    }
                default: 
-                   *bp++ = c;
+                   ADDCHR(c);
                    continue;
                case ']': 
-                   *bp++ = c;
+                   ADDCHR(c);
                    *bp = 0;
                    return (last_lex = LX_DLIT);
            }
-
-    *bp++ = c;
+    }
+    
+    ADDCHR(c);
     *bp = 0;
     for (i = 0; special[i].lx_chr != 0; i++)
        if (c == special[i].lx_chr)
@@ -876,7 +875,7 @@ my_lex (char *buffer)
                goto got_atom;
        if (iscntrl (c) || isspace (c))
            break;
-       *bp++ = c;
+       ADDCHR(c);
     }
 got_atom: ;
     if (c == 0)
@@ -887,6 +886,11 @@ got_atom: ;
     last_lex = !gotat || cp == NULL || strchr(cp, '<') != NULL
        ? LX_ATOM : LX_AT;
     return last_lex;
+
+ my_lex_buffull:
+    /* Out of buffer space. *bp is the last byte in the buffer */
+    *bp = 0;
+    return (last_lex = LX_ERR);
 }
 
 
@@ -919,8 +923,7 @@ mfgets (FILE *in, char **bp)
     static char *pp = NULL;
 
     if (pp == NULL)
-       if (!(pp = malloc ((size_t) (len = BUFSIZ))))
-           return NOTOK;
+       pp = mh_xmalloc ((size_t) (len = BUFSIZ));
 
     for (ep = (cp = pp) + len - 2;;) {
        switch (i = getc (in)) {
@@ -960,13 +963,8 @@ mfgets (FILE *in, char **bp)
                break;
        }
        if (cp >= ep) {
-           if (!(dp = realloc (pp, (size_t) (len += BUFSIZ)))) {
-               free (pp);
-               pp = NULL;
-               return NOTOK;
-           }
-           else
-               cp += dp - pp, ep = (pp = cp) + len - 2;
+           dp = mh_xrealloc (pp, (size_t) (len += BUFSIZ));
+           cp += dp - pp, ep = (pp = cp) + len - 2;
        }
     }
 }