/*
* 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 *);
}
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;
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) {
}
#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')
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);
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 {
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;
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))
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);
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);
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.
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))
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);
#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) */
FILE *scnout = NULL;
char name[NAMESZ];
static int rlwidth, slwidth;
+ static size_t scanl_size;
/* first-time only initialization */
if (!scanl) {
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");
}
}
- 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;