diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2010-10-22 14:11:23 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2010-10-22 14:11:23 +0000 |
commit | 84c6af6286e5fd5f09bbf5e8a8e306b5df1472ab (patch) | |
tree | 5cc0aebe620226195e410cb3b3500b44c95cf5da /usr.bin/fold/fold.c | |
parent | 9d599c067d063aa2804191334885e1f8af8dadef (diff) |
Fix a crash when mixing the legacy width option (e.g. fold -70)
with getopt()-style options, such as "fold -b70". Mixing the
legacy width with another option is no longer permitted. This
matches legacy behavior and other implementations. OK kili@
Diffstat (limited to 'usr.bin/fold/fold.c')
-rw-r--r-- | usr.bin/fold/fold.c | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/usr.bin/fold/fold.c b/usr.bin/fold/fold.c index 822aa4e786e..bba27d1f3d9 100644 --- a/usr.bin/fold/fold.c +++ b/usr.bin/fold/fold.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fold.c,v 1.12 2009/10/27 23:59:38 deraadt Exp $ */ +/* $OpenBSD: fold.c,v 1.13 2010/10/22 14:11:22 millert Exp $ */ /* $NetBSD: fold.c,v 1.6 1995/09/01 01:42:44 jtc Exp $ */ /*- @@ -37,6 +37,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <ctype.h> #include <err.h> #include <limits.h> @@ -44,20 +45,21 @@ static void fold(int); static int new_column_position(int, int); +static __dead void usage(void); int count_bytes = 0; int split_words = 0; int main(int argc, char *argv[]) { - int ch; - int width; - char *p; - char *w; + int ch, lastch, newarg, prevoptind, width; const char *errstr; - width = -1; - while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1) + width = 0; + lastch = '\0'; + prevoptind = 1; + newarg = 1; + while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1) { switch (ch) { case 'b': count_bytes = 1; @@ -73,28 +75,27 @@ main(int argc, char *argv[]) break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - if (width == -1) { - p = argv[optind - 1]; - if (p[0] == '-' && p[1] == ch && !p[2]) - w = ++p; - else - w = argv[optind] + 1; - - width = strtonum(w, 1, INT_MAX, &errstr); - if (errstr != NULL) - errx(1, "illegal width value, %s: %s", - errstr, optarg); - } + if (newarg) + width = 0; + else if (!isdigit(lastch)) + usage(); + if (width > INT_MAX / 10) + errx(1, "illegal width value, too large"); + width = (width * 10) + (ch - '0'); + if (width < 1) + errx(1, "illegal width value, too small"); break; default: - (void)fprintf(stderr, - "usage: fold [-bs] [-w width] [file ...]\n"); - exit(1); + usage(); } + lastch = ch; + newarg = optind != prevoptind; + prevoptind = optind; + } argv += optind; argc -= optind; - if (width == -1) + if (width == 0) width = DEFLINEWIDTH; if (!*argv) @@ -215,3 +216,10 @@ new_column_position(int col, int ch) return col; } + +static __dead void +usage(void) +{ + (void)fprintf(stderr, "usage: fold [-bs] [-w width] [file ...]\n"); + exit(1); +} |