Hi, Currently, jot(1) restricts arguments given to the `-s', `-b' and `-w' options to BUFSIZ characters; this is a typical misuse of that constant, which has essentially nothing to do with the expected maximum size of argv's elements. Besides, I have actually hit this limit multiple times recently, so I decided to fix it.
In the case of `-s', this was trivial. In the case of `-b' and `-w', the quick and dirty solution would have been to declare a larger `format' buffer, but the proper way is to allocate the required length dynamically, as shown below. Index: jot.c =================================================================== RCS file: /cvs/src/usr.bin/jot/jot.c,v retrieving revision 1.41 diff -u -p -r1.41 jot.c --- jot.c 30 Dec 2017 07:21:10 -0000 1.41 +++ jot.c 31 Dec 2017 13:50:59 -0000 @@ -59,8 +59,8 @@ static double begin = 1; static double ender = 100; static double step = 1; -static char format[BUFSIZ]; -static char sepstring[BUFSIZ] = "\n"; +static char *format = NULL; +static char *sepstring = "\n"; static int prec = -1; static bool boring; static bool chardata; @@ -85,7 +85,7 @@ main(int argc, char *argv[]) unsigned int mask = 0; int n = 0; int ch; - const char *errstr; + const char *errstr; if (pledge("stdio", NULL) == -1) err(1, "pledge"); @@ -94,9 +94,9 @@ main(int argc, char *argv[]) switch (ch) { case 'b': boring = true; - if (strlcpy(format, optarg, sizeof(format)) >= - sizeof(format)) - errx(1, "-b word too long"); + free(format); + if ((format = strdup(optarg)) == NULL) + err(1, NULL); break; case 'c': chardata = true; @@ -114,14 +114,12 @@ main(int argc, char *argv[]) randomize = true; break; case 's': - if (strlcpy(sepstring, optarg, sizeof(sepstring)) >= - sizeof(sepstring)) - errx(1, "-s string too long"); + sepstring = optarg; break; case 'w': - if (strlcpy(format, optarg, sizeof(format)) >= - sizeof(format)) - errx(1, "-w word too long"); + free(format); + if ((format = strdup(optarg)) == NULL) + err(1, NULL); break; default: usage(); @@ -176,7 +174,8 @@ main(int argc, char *argv[]) argv[4]); } - getformat(); + if (!boring) + getformat(); if (!randomize) { /* @@ -356,32 +355,29 @@ static void getformat(void) { char *p, *p2; - int dot, hash, space, sign, numbers = 0; - size_t sz; + int n, dot, hash, space, sign, numbers; + size_t len = 0; - if (boring) /* no need to bother */ - return; - for (p = format; *p != '\0'; p++) /* look for '%' */ - if (*p == '%') { - if (*(p+1) != '%') - break; - p++; /* leave %% alone */ - } - sz = sizeof(format) - strlen(format) - 1; - if (*p == '\0' && !chardata) { - int n; - - n = snprintf(p, sz, "%%.%df", prec); - if (n == -1 || n >= (int)sz) - errx(1, "-w word too long"); - } else if (*p == '\0' && chardata) { - if (strlcpy(p, "%c", sz) >= sz) - errx(1, "-w word too long"); + if ((p = format) != NULL) { + while ((p = strchr(p, '%')) != NULL && p[1] == '%') + p += 2; + len = strlen(format); + } + if (p == NULL && !chardata) { + if ((n = snprintf(NULL, 0, "%%.%df", prec)) == -1 || + (format = realloc(format, len + n + 1)) == NULL || + snprintf(format + len, n + 1, "%%.%df", prec) != n) + err(1, NULL); + } else if (p == NULL && chardata) { + if ((format = realloc(format, len + sizeof("%c"))) == NULL) + err(1, NULL); + strcpy(format + len, "%c"); intdata = true; } else if (*(p+1) == '\0') { /* cannot end in single '%' */ - if (strlcat(format, "%", sizeof(format)) >= sizeof(format)) - errx(1, "-w word too long"); + if ((format = realloc(format, len + sizeof("%"))) == NULL) + err(1, NULL); + strcpy(format + len, "%"); } else { /* * Allow conversion format specifiers of the form @@ -456,9 +452,10 @@ fmt_broken: p++; else if (*p == '%' && *(p+1) == '\0') { /* cannot end in single '%' */ - if (strlcat(format, "%", sizeof(format)) >= - sizeof(format)) - errx(1, "-w word too long"); + if ((format = realloc(format, + len + sizeof("%"))) == NULL) + err(1, NULL); + strcpy(format + len, "%"); break; } } Regards, kshe