diff options
author | ache <ache@FreeBSD.org> | 2001-08-15 02:07:47 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2001-08-15 02:07:47 +0000 |
commit | 9d7273169f482f1f74606c9f559ecc986f668088 (patch) | |
tree | c651de630103d0b82ee727fa499a87af0697e6f6 /lib/libc/stdio/stdio.c | |
parent | 679dd2c9f81d6f490f3db2613cb62f20c7cf93ab (diff) | |
download | FreeBSD-src-9d7273169f482f1f74606c9f559ecc986f668088.zip FreeBSD-src-9d7273169f482f1f74606c9f559ecc986f668088.tar.gz |
1) Disallow negative seek as POSIX require for fseek{o} (but not for lseek):
"[EINVAL] ... The resulting file-position indicator would be set to a
negative value."
Moreover, in real life negative seek in stdio cause EOF indicator cleared
and not set again forever even if EOF returned.
2) Catch few possible off_t overflows.
Reviewed by: arch discussion
Diffstat (limited to 'lib/libc/stdio/stdio.c')
-rw-r--r-- | lib/libc/stdio/stdio.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/libc/stdio/stdio.c b/lib/libc/stdio/stdio.c index 57be5bb..58fafcb 100644 --- a/lib/libc/stdio/stdio.c +++ b/lib/libc/stdio/stdio.c @@ -43,6 +43,7 @@ static const char rcsid[] = #endif /* LIBC_SCCS and not lint */ #include "namespace.h" +#include <errno.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> @@ -94,10 +95,24 @@ __sseek(cookie, offset, whence) register FILE *fp = cookie; register off_t ret; + /* + * Disallow negative seeks per POSIX. + * It is needed here to help upper level caller + * (fseek) in the cases it can't detect. + */ + if (whence == SEEK_SET && (off_t)offset < 0) { + errno = EINVAL; + return (-1); + } ret = lseek(fp->_file, (off_t)offset, whence); - if (ret == -1) + if (ret < 0) { + if (ret != -1) { + /* Resulting seek is negative! */ + ret = -1; + errno = EINVAL; + } fp->_flags &= ~__SOFF; - else { + } else { fp->_flags |= __SOFF; fp->_offset = ret; } |