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
This commit is contained in:
Andrey A. Chernov 2001-08-15 02:07:47 +00:00
parent ba8140a6f6
commit d9e3eff33a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=81666
3 changed files with 45 additions and 13 deletions

View File

@ -180,18 +180,12 @@ is not a seekable stream.
.It Bq Er EINVAL
The
.Fa whence
argument to
.Fn fseek
was not
.Dv SEEK_SET ,
.Dv SEEK_END ,
or
.Dv SEEK_CUR .
argument is invalid.
The resulting file-position
indicator would be set to a negative value.
.It Bq Er EOVERFLOW
For
.Fn ftell ,
the resulting file offset would be a value which
cannot be represented correctly in an object of type long.
The resulting file offset would be a value which
cannot be represented correctly in an object of type requested.
.El
.Pp
The functions

View File

@ -132,12 +132,26 @@ _fseeko(fp, offset, whence)
} else if (fp->_flags & __SWR && fp->_p != NULL)
curoff += fp->_p - fp->_bf._base;
if (offset > 0 && offset + (off_t)curoff < 0) {
errno = EOVERFLOW;
return (EOF);
}
offset += curoff;
/* Disallow negative seeks per POSIX */
if (offset < 0) {
errno = EINVAL;
return (EOF);
}
whence = SEEK_SET;
havepos = 1;
break;
case SEEK_SET:
/* Disallow negative seeks per POSIX */
if (offset < 0) {
errno = EINVAL;
return (EOF);
}
case SEEK_END:
curoff = 0; /* XXX just to keep gcc quiet */
havepos = 0;
@ -180,7 +194,16 @@ _fseeko(fp, offset, whence)
else {
if (_fstat(fp->_file, &st))
goto dumb;
if (offset > 0 && st.st_size + offset < 0) {
errno = EOVERFLOW;
return (EOF);
}
target = st.st_size + offset;
/* Disallow negative seeks per POSIX */
if ((off_t)target < 0) {
errno = EINVAL;
return (EOF);
}
}
if (!havepos) {

View File

@ -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;
}