From 37c05b6267140d4afd11ad96cc244e8cd851083c Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sat, 28 Oct 2000 11:49:52 +0000 Subject: [PATCH] Include assert.h. (fillrand): Add a parameter, size_max. Add an assertion. Adjust caller. (dopass): Break out of the `for (;;)' loop if size < offset. That can happen now that dopass is called with SIZE == -1. (do_wipefd): Accept a length of zero only for a regular file. If lseek fails or returns 0 for a non-regular file, let dopass determine the length. Inspired by a patch from Alan Iwi. --- src/shred.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/shred.c b/src/shred.c index c523d09..9c1262f 100644 --- a/src/shred.c +++ b/src/shred.c @@ -83,6 +83,7 @@ #include #include +#include #include #include #include @@ -990,13 +991,14 @@ fillpattern (int type, unsigned char *r, size_t size) } /* - * Fill a buffer with random data. - * size is rounded UP to a multiple of ISAAC_BYTES. + * Fill a buffer, R (of size SIZE_MAX), with random data. + * SIZE is rounded UP to a multiple of ISAAC_BYTES. */ static void -fillrand (struct isaac_state *s, word32 *r, size_t size) +fillrand (struct isaac_state *s, word32 *r, size_t size_max, size_t size) { size = (size + ISAAC_BYTES - 1) / ISAAC_BYTES; + assert (size <= size_max); while (size--) { @@ -1083,12 +1085,14 @@ dopass (int fd, char const *qname, off_t *sizep, int type, lim = sizeof r; if ((off_t) lim > size - offset && size != -1) { + if (size < offset) + break; lim = (size_t) (size - offset); if (!lim) break; } if (type < 0) - fillrand (s, r, lim); + fillrand (s, r, sizeof r, lim); /* Loop to retry partial writes. */ for (soff = 0; soff < lim; soff += ssize) { @@ -1422,17 +1426,33 @@ do_wipefd (int fd, char const *qname, struct isaac_state *s, size = flags->size; if (size == -1) { - size = (S_ISREG (st.st_mode) - ? st.st_size - : lseek (fd, (off_t) 0, SEEK_END)); - if (size < (S_ISREG (st.st_mode) ? 0 : -1)) + /* Accept a length of zero only if it's a regular file. + For any other type of file, try to get the size another way. */ + if (S_ISREG (st.st_mode)) { - error (0, 0, _("%s: file has negative size"), qname); - return -1; + size = st.st_size; + if (size < 0) + { + error (0, 0, _("%s: file has negative size"), qname); + return -1; + } } + else + { + size = lseek (fd, (off_t) 0, SEEK_END); + if (size <= 0) + { + /* We are unable to determine the length, up front. + Let dopass do that as part of its first iteration. */ + size = -1; + } + } + if (0 <= size && !(flags->exact)) { size += ST_BLKSIZE (st) - 1 - (size - 1) % ST_BLKSIZE (st); + + /* If in rounding up, we've just overflowed, use the maximum. */ if (size < 0) size = TYPE_MAXIMUM (off_t); } -- 2.7.4