diff options
author | des <des@FreeBSD.org> | 2010-03-04 13:35:57 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2010-03-04 13:35:57 +0000 |
commit | 834fb25a9ed2240101506d137b5be7d71c75f306 (patch) | |
tree | 4002c72cd1ed11909f7640bea343988cfcf63c5b /lib/libc/stdio | |
parent | 98b742f57cafbed05c101e60cc131f5980f044d0 (diff) | |
parent | 787cf8d03f1c58ada088933408f30fd63de85bf2 (diff) | |
download | FreeBSD-src-834fb25a9ed2240101506d137b5be7d71c75f306.zip FreeBSD-src-834fb25a9ed2240101506d137b5be7d71c75f306.tar.gz |
IFH@204581
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r-- | lib/libc/stdio/fgetws.c | 2 | ||||
-rw-r--r-- | lib/libc/stdio/findfp.c | 2 | ||||
-rw-r--r-- | lib/libc/stdio/fread.c | 23 | ||||
-rw-r--r-- | lib/libc/stdio/funopen.c | 10 | ||||
-rw-r--r-- | lib/libc/stdio/fvwrite.c | 2 | ||||
-rw-r--r-- | lib/libc/stdio/fwrite.c | 20 | ||||
-rw-r--r-- | lib/libc/stdio/getc.3 | 5 | ||||
-rw-r--r-- | lib/libc/stdio/getdelim.c | 4 | ||||
-rw-r--r-- | lib/libc/stdio/getline.3 | 3 | ||||
-rw-r--r-- | lib/libc/stdio/mktemp.c | 4 | ||||
-rw-r--r-- | lib/libc/stdio/printf.3 | 6 | ||||
-rw-r--r-- | lib/libc/stdio/sprintf.c | 10 | ||||
-rw-r--r-- | lib/libc/stdio/sscanf.c | 25 | ||||
-rw-r--r-- | lib/libc/stdio/vfwprintf.c | 2 | ||||
-rw-r--r-- | lib/libc/stdio/vsscanf.c | 11 | ||||
-rw-r--r-- | lib/libc/stdio/xprintf_time.c | 3 |
16 files changed, 69 insertions, 63 deletions
diff --git a/lib/libc/stdio/fgetws.c b/lib/libc/stdio/fgetws.c index bbc0299..550843d 100644 --- a/lib/libc/stdio/fgetws.c +++ b/lib/libc/stdio/fgetws.c @@ -89,7 +89,7 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) if (!__mbsinit(&fp->_mbstate)) /* Incomplete character */ goto error; - *wsp++ = L'\0'; + *wsp = L'\0'; FUNLOCKFILE(fp); return (ws); diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c index 586e15c..5bc4af7 100644 --- a/lib/libc/stdio/findfp.c +++ b/lib/libc/stdio/findfp.c @@ -168,7 +168,7 @@ __warn_references(f_prealloc, "warning: this program uses f_prealloc(), which is not recommended."); void -f_prealloc() +f_prealloc(void) { struct glue *g; int n; diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c index 6253856..ad3ea29 100644 --- a/lib/libc/stdio/fread.c +++ b/lib/libc/stdio/fread.c @@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93"; __FBSDID("$FreeBSD$"); #include "namespace.h" +#include <errno.h> +#include <stdint.h> #include <stdio.h> #include <string.h> #include "un-namespace.h" @@ -69,8 +71,27 @@ __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) /* * ANSI and SUSv2 require a return value of 0 if size or count are 0. */ - if ((resid = count * size) == 0) + if ((count == 0) || (size == 0)) return (0); + + /* + * Check for integer overflow. As an optimization, first check that + * at least one of {count, size} is at least 2^16, since if both + * values are less than that, their product can't possible overflow + * (size_t is always at least 32 bits on FreeBSD). + */ + if (((count | size) > 0xFFFF) && + (count > SIZE_MAX / size)) { + errno = EINVAL; + fp->_flags |= __SERR; + return (0); + } + + /* + * Compute the (now required to not overflow) number of bytes to + * read and actually do the work. + */ + resid = count * size; ORIENT(fp, -1); if (fp->_r < 0) fp->_r = 0; diff --git a/lib/libc/stdio/funopen.c b/lib/libc/stdio/funopen.c index 9535340..573589f 100644 --- a/lib/libc/stdio/funopen.c +++ b/lib/libc/stdio/funopen.c @@ -42,11 +42,11 @@ __FBSDID("$FreeBSD$"); #include "local.h" FILE * -funopen(cookie, readfn, writefn, seekfn, closefn) - const void *cookie; - int (*readfn)(), (*writefn)(); - fpos_t (*seekfn)(void *cookie, fpos_t off, int whence); - int (*closefn)(); +funopen(const void *cookie, + int (*readfn)(void *, char *, int), + int (*writefn)(void *, const char *, int), + fpos_t (*seekfn)(void *, fpos_t, int), + int (*closefn)(void *)) { FILE *fp; int flags; diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c index fd69eb9..7206676 100644 --- a/lib/libc/stdio/fvwrite.c +++ b/lib/libc/stdio/fvwrite.c @@ -60,7 +60,7 @@ __sfvwrite(fp, uio) char *nl; int nlknown, nldist; - if ((len = uio->uio_resid) == 0) + if (uio->uio_resid == 0) return (0); /* make sure we can write */ if (prepwrite(fp) != 0) diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c index cf52e42..acac943 100644 --- a/lib/libc/stdio/fwrite.c +++ b/lib/libc/stdio/fwrite.c @@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93"; __FBSDID("$FreeBSD$"); #include "namespace.h" +#include <errno.h> +#include <stdint.h> #include <stdio.h> #include "un-namespace.h" #include "local.h" @@ -60,10 +62,24 @@ fwrite(buf, size, count, fp) /* * ANSI and SUSv2 require a return value of 0 if size or count are 0. */ - n = count * size; - if (n == 0) + if ((count == 0) || (size == 0)) return (0); + /* + * Check for integer overflow. As an optimization, first check that + * at least one of {count, size} is at least 2^16, since if both + * values are less than that, their product can't possible overflow + * (size_t is always at least 32 bits on FreeBSD). + */ + if (((count | size) > 0xFFFF) && + (count > SIZE_MAX / size)) { + errno = EINVAL; + fp->_flags |= __SERR; + return (0); + } + + n = count * size; + iov.iov_base = (void *)buf; uio.uio_resid = iov.iov_len = n; uio.uio_iov = &iov; diff --git a/lib/libc/stdio/getc.3 b/lib/libc/stdio/getc.3 index c8b9386..d0f3c15 100644 --- a/lib/libc/stdio/getc.3 +++ b/lib/libc/stdio/getc.3 @@ -56,7 +56,7 @@ .Ft int .Fn getchar void .Ft int -.Fn getchar_unlocked "void" +.Fn getchar_unlocked void .Ft int .Fn getw "FILE *stream" .Sh DESCRIPTION @@ -141,7 +141,7 @@ until the condition is cleared with .Sh STANDARDS The .Fn fgetc , -.Fn getc +.Fn getc , and .Fn getchar functions @@ -167,4 +167,3 @@ The size and byte order of an varies from one machine to another, and .Fn getw is not recommended for portable applications. -.Pp diff --git a/lib/libc/stdio/getdelim.c b/lib/libc/stdio/getdelim.c index 7af154f..d7d5627 100644 --- a/lib/libc/stdio/getdelim.c +++ b/lib/libc/stdio/getdelim.c @@ -120,8 +120,8 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim, goto error; } - if (*linecapp == 0) - *linep = NULL; + if (*linep == NULL) + *linecapp = 0; if (fp->_r <= 0 && __srefill(fp)) { /* If fp is at EOF already, we just need space for the NUL. */ diff --git a/lib/libc/stdio/getline.3 b/lib/libc/stdio/getline.3 index 0465f93..a5b39da 100644 --- a/lib/libc/stdio/getline.3 +++ b/lib/libc/stdio/getline.3 @@ -78,7 +78,8 @@ and .Fn getline functions return the number of characters written, excluding the terminating -.Dv NUL . +.Dv NUL +character. The value \-1 is returned if an error occurs, or if end-of-file is reached. .Sh EXAMPLES The following code fragment reads lines from a file and diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c index 3f1e699..a30b930 100644 --- a/lib/libc/stdio/mktemp.c +++ b/lib/libc/stdio/mktemp.c @@ -116,6 +116,10 @@ _gettemp(path, doopen, domkdir, slen) for (trv = path; *trv != '\0'; ++trv) ; + if (trv - path >= MAXPATHLEN) { + errno = ENAMETOOLONG; + return (0); + } trv -= slen; suffp = trv; --trv; diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3 index 27d5bf0..8de2bb8 100644 --- a/lib/libc/stdio/printf.3 +++ b/lib/libc/stdio/printf.3 @@ -32,7 +32,7 @@ .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd March 3, 2009 +.Dd December 2, 2009 .Dt PRINTF 3 .Os .Sh NAME @@ -55,7 +55,7 @@ .Ft int .Fn asprintf "char **ret" "const char *format" ... .Ft int -.Fn dprintf "int" "const char * restrict format" ... +.Fn dprintf "int fd" "const char * restrict format" ... .In stdarg.h .Ft int .Fn vprintf "const char * restrict format" "va_list ap" @@ -812,7 +812,7 @@ available. The conversion formats .Cm \&%D , \&%O , and -.Cm %U +.Cm \&%U are not standard and are provided only for backward compatibility. The effect of padding the diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c index aaaae55..b55bd6c 100644 --- a/lib/libc/stdio/sprintf.c +++ b/lib/libc/stdio/sprintf.c @@ -46,17 +46,9 @@ sprintf(char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; - FILE f; - f._file = -1; - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = INT_MAX; - f._orientation = 0; - memset(&f._mbstate, 0, sizeof(mbstate_t)); va_start(ap, fmt); - ret = __vfprintf(&f, fmt, ap); + ret = vsprintf(str, fmt, ap); va_end(ap); - *f._p = 0; return (ret); } diff --git a/lib/libc/stdio/sscanf.c b/lib/libc/stdio/sscanf.c index 3c792e0..c793b86 100644 --- a/lib/libc/stdio/sscanf.c +++ b/lib/libc/stdio/sscanf.c @@ -41,37 +41,14 @@ __FBSDID("$FreeBSD$"); #include <stdarg.h> #include "local.h" -static int eofread(void *, char *, int); - -/* ARGSUSED */ -static int -eofread(cookie, buf, len) - void *cookie; - char *buf; - int len; -{ - - return (0); -} - int sscanf(const char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; - FILE f; - f._file = -1; - f._flags = __SRD; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._r = strlen(str); - f._read = eofread; - f._ub._base = NULL; - f._lb._base = NULL; - f._orientation = 0; - memset(&f._mbstate, 0, sizeof(mbstate_t)); va_start(ap, fmt); - ret = __svfscanf(&f, fmt, ap); + ret = vsscanf(str, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c index f3768de..d34f559 100644 --- a/lib/libc/stdio/vfwprintf.c +++ b/lib/libc/stdio/vfwprintf.c @@ -293,7 +293,7 @@ __mbsconv(char *mbsarg, int prec) * number of characters to print. */ p = mbsarg; - insize = nchars = 0; + insize = nchars = nconv = 0; mbs = initial_mbs; while (nchars != (size_t)prec) { nconv = mbrlen(p, MB_CUR_MAX, &mbs); diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c index e5e9691..22b5d2b 100644 --- a/lib/libc/stdio/vsscanf.c +++ b/lib/libc/stdio/vsscanf.c @@ -45,20 +45,15 @@ eofread(void *, char *, int); /* ARGSUSED */ static int -eofread(cookie, buf, len) - void *cookie; - char *buf; - int len; +eofread(void *cookie, char *buf, int len) { return (0); } int -vsscanf(str, fmt, ap) - const char * __restrict str; - const char * __restrict fmt; - __va_list ap; +vsscanf(const char * __restrict str, const char * __restrict fmt, + __va_list ap) { FILE f; diff --git a/lib/libc/stdio/xprintf_time.c b/lib/libc/stdio/xprintf_time.c index 81697f1..9d732fe 100644 --- a/lib/libc/stdio/xprintf_time.c +++ b/lib/libc/stdio/xprintf_time.c @@ -64,7 +64,6 @@ __printf_render_time(struct __printf_io *io, const struct printf_info *pi, const intmax_t t, tx; int i, prec, nsec; - prec = 0; if (pi->is_long) { tv = *((struct timeval **)arg[0]); t = tv->tv_sec; @@ -78,6 +77,8 @@ __printf_render_time(struct __printf_io *io, const struct printf_info *pi, const } else { tp = *((time_t **)arg[0]); t = *tp; + nsec = 0; + prec = 0; } p = buf; |