Added argument to fmt_scan() to specify the buffer size.
authorDavid Levine <levinedl@acm.org>
Sat, 3 Nov 2012 03:45:07 +0000 (22:45 -0500)
committerDavid Levine <levinedl@acm.org>
Sat, 3 Nov 2012 03:45:07 +0000 (22:45 -0500)
h/fmt_scan.h
sbr/fmt_scan.c
uip/ap.c
uip/comp.c
uip/dp.c
uip/forwsbr.c
uip/mhlsbr.c
uip/rcvdist.c
uip/replsbr.c
uip/scansbr.c

index d8fab61..837780c 100644 (file)
@@ -90,7 +90,7 @@ struct format {
 /*
  * prototypes
  */
-struct format *fmt_scan (struct format *, char *, int, int *);
+struct format *fmt_scan (struct format *, char *, size_t, int, int *);
 char *new_fs (char *, char *, char *);
 int fmt_compile (char *, struct format **);
 char *formataddr(char *, char *);
index 74cfd92..51ba24c 100644 (file)
@@ -317,7 +317,7 @@ get_x400_comp (char *mbox, char *key, char *buffer, int buffer_len)
 }
 
 struct format *
-fmt_scan (struct format *format, char *scanl, int width, int *dat)
+fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
 {
     char *cp, *ep;
     unsigned char *sp;
@@ -332,8 +332,11 @@ fmt_scan (struct format *format, char *scanl, int width, int *dat)
     struct tws *tws;
     struct mailname *mn;
 
+    /* ep keeps track of displayed characters.  They're limited by width.
+       The total number of characters, cp - scanl + 1 (for trailing NULL),
+       includes invisible control characters and is limited by max. */
     cp = scanl;
-    ep = scanl + width - 1;
+    ep = scanl + (width <= (int) max ? width : (int) max) - 1;
 
     for (fmt = format; fmt->f_type != FT_DONE; fmt++)
        switch (fmt->f_type) {
@@ -974,9 +977,14 @@ fmt_scan (struct format *format, char *scanl, int width, int *dat)
     }
 #ifndef JLR
     finished:;
-    if (cp[-1] != '\n')
-       *cp++ = '\n';
-    *cp   = 0;
+    if (cp > scanl  &&  cp[-1] != '\n') {
+       if (cp - scanl < (int) max - 1) {
+           *cp++ = '\n';
+       } else {
+           cp[-1] = '\n';
+       }
+    }
+    *cp = '\0';
     return ((struct format *)0);
 #else /* JLR */
     if (cp[-1] != '\n')
index b5b0c5b..fdb47e2 100644 (file)
--- a/uip/ap.c
+++ b/uip/ap.c
@@ -190,7 +190,7 @@ process (char *arg, int length, int norm)
        if (cptr)
            cptr->c_text = p->pq_error;
 
-       fmt_scan (fmt, buffer, length, dat);
+       fmt_scan (fmt, buffer, sizeof buffer - 1, length, dat);
        fputs (buffer, stdout);
 
        free (p->pq_text);
index 29ca1b7..f7a8f8f 100644 (file)
@@ -392,7 +392,7 @@ try_it_again:
        dat[2] = 0;
        dat[3] = outputlinelen;
        dat[4] = 0;
-       fmt_scan(fmt, scanl, i, dat);
+       fmt_scan(fmt, scanl, i + 1, i, dat);
        write(out, scanl, strlen(scanl));
        free(scanl);
     } else {
index a66beed..95a7163 100644 (file)
--- a/uip/dp.c
+++ b/uip/dp.c
@@ -144,7 +144,7 @@ process (char *date, int length)
     FINDCOMP (cptr, "text");
     if (cptr)
        cptr->c_text = date;
-    fmt_scan (fmt, buffer, length, dat);
+    fmt_scan (fmt, buffer, sizeof buffer - 1, length, dat);
     fputs (buffer, stdout);
 
     return status;
index 79dfd10..9abf20d 100644 (file)
@@ -191,7 +191,7 @@ finished:
        adios ("dup", "unable to");
 
     line = mh_xmalloc ((unsigned) fmtsize);
-    fmt_scan (fmt, line, fmtsize, dat);
+    fmt_scan (fmt, line, fmtsize - 1, fmtsize, dat);
     fputs (line, tmp);
     free (line);
     if (fclose (tmp))
index 8cd5c34..9964fa0 100644 (file)
@@ -1118,7 +1118,7 @@ mcomp_format (struct mcomp *c1, struct mcomp *c2)
            if (!cp[1])
                *cp = 0;
 
-       fmt_scan (c1->c_fmt, buffer, sizeof(buffer) - 1, dat);
+       fmt_scan (c1->c_fmt, buffer, sizeof buffer - 1, sizeof buffer - 1, dat);
        /* Don't need to append a newline, dctime() already did */
        c2->c_text = getcpy (buffer);
 
@@ -1149,7 +1149,7 @@ mcomp_format (struct mcomp *c1, struct mcomp *c2)
        if (cptr)
            cptr->c_text = p->pq_error;
 
-       fmt_scan (c1->c_fmt, buffer, sizeof(buffer) - 1, dat);
+       fmt_scan (c1->c_fmt, buffer, sizeof buffer - 1, sizeof buffer - 1, dat);
        if (*buffer) {
            if (c2->c_text)
                c2->c_text = add (",\n", c2->c_text);
@@ -1945,7 +1945,7 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int state, FILE *fp)
 
        for (a = c1->c_f_args, i = 1; a != NULL; a = a->a_next, i++) {
            args[i] = mh_xmalloc(BUFSIZ);
-           fmt_scan(a->a_fmt, args[i], BUFSIZ, dat);
+           fmt_scan(a->a_fmt, args[i], BUFSIZ - 1, BUFSIZ, dat);
            /*
             * fmt_scan likes to put a trailing newline at the end of the
             * format string.  If we have one, get rid of it.
index 8ff0365..4061735 100644 (file)
@@ -262,7 +262,7 @@ finished: ;
     scanl = mh_xmalloc ((size_t) i + 2);
     dat[0] = dat[1] = dat[2] = dat[4] = 0;
     dat[3] = outputlinelen;
-    fmt_scan (fmt, scanl, i, dat);
+    fmt_scan (fmt, scanl, i + 1, i, dat);
     fputs (scanl, out);
 
     if (ferror (out))
index a6d0f23..f6ccd35 100644 (file)
@@ -237,7 +237,7 @@ finished:
     dat[2] = 0;
     dat[3] = outputlinelen;
     dat[4] = 0;
-    fmt_scan (fmt, scanl, i, dat);
+    fmt_scan (fmt, scanl, i + 1, i, dat);
     fputs (scanl, out);
     if (badaddrs) {
        fputs ("\nrepl: bad addresses:\n", out);
index 3d66bcf..480cab5 100644 (file)
 #define SBUFSIZ 512
 
 static struct format *fmt;
-#ifdef JLR
-static struct format *fmt_top;
-#endif /* JLR */
-
 static struct comp *datecomp;          /* pntr to "date" comp             */
 static struct comp *bodycomp;          /* pntr to "body" pseudo-comp      *
                                         * (if referenced)                 */
@@ -78,6 +74,7 @@ scan (FILE *inb, int innum, int outnum, char *nfs, int width, int curflg,
     FILE *scnout = NULL;
     char name[NAMESZ];
     static int rlwidth, slwidth;
+    static size_t scanl_size;
 
     /* first-time only initialization */
     if (!scanl) {
@@ -88,16 +85,16 @@ scan (FILE *inb, int innum, int outnum, char *nfs, int width, int curflg,
                width = MAXSCANL;
        }
        dat[3] = slwidth = width;
-       scanl = (char *) mh_xmalloc((size_t) SCAN_CHARWIDTH * (slwidth + 2) );
+       /* Arbitrarily allocate 20 * slwidth to provide room for lots
+          of escape sequences. */
+       scanl_size = SCAN_CHARWIDTH * (20 * slwidth + 2);
+       scanl = (char *) mh_xmalloc (scanl_size);
        if (outnum)
            umask(~m_gmprot());
 
        /* Compile format string */
        ncomps = fmt_compile (nfs, &fmt) + 1;
 
-#ifdef JLR
-       fmt_top = fmt;
-#endif /* JLR */
        FINDCOMP(bodycomp, "body");
        FINDCOMP(datecomp, "date");
        FINDCOMP(cptr, "folder");
@@ -330,13 +327,7 @@ finished:
        }
     }
 
-    fmt_scan (fmt, scanl, slwidth, dat);
-
-#if 0
-    fmt = fmt_scan (fmt, scanl, slwidth, dat);
-    if (!fmt)
-       fmt = fmt_top;          /* reset for old format files */
-#endif
+    fmt_scan (fmt, scanl, scanl_size, slwidth, dat);
 
     if (bodycomp)
        bodycomp->c_text = saved_c_text;