diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2015-11-10 14:42:42 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2015-11-10 14:42:42 +0000 |
commit | 393f9e046b96ca482a1e9dc4d855ad63b9a80bdc (patch) | |
tree | 5fb9dc5eaa793b0d6f3c043ee89927549b2f617d /usr.bin | |
parent | 12ec48656fd5a6d755006efb702040930a4eacee (diff) |
With -H, do not overrun your static buffer on files longer than 4 kB.
With -K, do not print bogus blank lines in case of premature EOF.
While here, completely rewrite get_line() in a modern style using
getline(3), ferror(3), strdup(3), and ssize_t for line lengths.
Completely get rid of the static buffer.
I wouldn't be very surprised if this fixes even more bugs
than the two ones mentioned above.
OK (and "amazing") deraadt@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/rs/rs.c | 56 |
1 files changed, 25 insertions, 31 deletions
diff --git a/usr.bin/rs/rs.c b/usr.bin/rs/rs.c index 7b5da82b1d4..5d702cf4509 100644 --- a/usr.bin/rs/rs.c +++ b/usr.bin/rs/rs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rs.c,v 1.27 2015/10/09 01:37:08 deraadt Exp $ */ +/* $OpenBSD: rs.c,v 1.28 2015/11/10 14:42:41 schwarze Exp $ */ /*- * Copyright (c) 1993 @@ -67,10 +67,10 @@ char **elem; char **endelem; char *curline; int allocsize = BUFSIZ; -int curlen; +ssize_t curlen; int irows, icols; int orows, ocols; -int maxlen; +ssize_t maxlen; int skip; int propgutter; char isep = ' ', osep = ' '; @@ -118,11 +118,13 @@ getfile(void) char **padto; while (skip--) { - get_line(); + if (get_line() == EOF) + return; if (flags & SKIPPRINT) puts(curline); } - get_line(); + if (get_line() == EOF) + return; if (flags & NOARGS && curlen < owidth) flags |= ONEPERLINE; if (flags & ONEPERLINE) @@ -303,37 +305,29 @@ prepfile(void) nelem = n; } -#define BSIZE 2048 -char ibuf[BSIZE]; /* two screenfuls should do */ - int get_line(void) /* get line; maintain curline, curlen; manage storage */ { - static int putlength; - static char *endblock = ibuf + BSIZE; - char *p; - int c, i; + static char *ibuf = NULL; + static size_t ibufsz = 0; - if (!irows) { - curline = ibuf; - putlength = flags & DETAILSHAPE; - } - else if (skip <= 0) { /* don't waste storage */ - curline += curlen + 1; - if (putlength) /* print length, recycle storage */ - printf(" %d line %d\n", curlen, irows); - } - if (!putlength && endblock - curline < BUFSIZ) { /* need storage */ - if (!(curline = malloc(BSIZE))) - errx(1, "File too large"); - endblock = curline + BSIZE; + if (irows > 0 && flags & DETAILSHAPE) + printf(" %zd line %d\n", curlen, irows); + + if ((curlen = getline(&ibuf, &ibufsz, stdin)) == EOF) { + if (ferror(stdin)) + err(1, NULL); + return EOF; } - for (p = curline, i = 1; i < BUFSIZ; *p++ = c, i++) - if ((c = getchar()) == EOF || c == '\n') - break; - *p = '\0'; - curlen = i - 1; - return(c); + if (curlen > 0 && ibuf[curlen - 1] == '\n') + ibuf[--curlen] = '\0'; + + if (skip >= 0 || flags & SHAPEONLY) + curline = ibuf; + else if ((curline = strdup(ibuf)) == NULL) + err(1, NULL); + + return 0; } char ** |