summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2010-03-04 13:35:57 +0000
committerdes <des@FreeBSD.org>2010-03-04 13:35:57 +0000
commit834fb25a9ed2240101506d137b5be7d71c75f306 (patch)
tree4002c72cd1ed11909f7640bea343988cfcf63c5b /lib/libc/stdio
parent98b742f57cafbed05c101e60cc131f5980f044d0 (diff)
parent787cf8d03f1c58ada088933408f30fd63de85bf2 (diff)
downloadFreeBSD-src-834fb25a9ed2240101506d137b5be7d71c75f306.zip
FreeBSD-src-834fb25a9ed2240101506d137b5be7d71c75f306.tar.gz
IFH@204581
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r--lib/libc/stdio/fgetws.c2
-rw-r--r--lib/libc/stdio/findfp.c2
-rw-r--r--lib/libc/stdio/fread.c23
-rw-r--r--lib/libc/stdio/funopen.c10
-rw-r--r--lib/libc/stdio/fvwrite.c2
-rw-r--r--lib/libc/stdio/fwrite.c20
-rw-r--r--lib/libc/stdio/getc.35
-rw-r--r--lib/libc/stdio/getdelim.c4
-rw-r--r--lib/libc/stdio/getline.33
-rw-r--r--lib/libc/stdio/mktemp.c4
-rw-r--r--lib/libc/stdio/printf.36
-rw-r--r--lib/libc/stdio/sprintf.c10
-rw-r--r--lib/libc/stdio/sscanf.c25
-rw-r--r--lib/libc/stdio/vfwprintf.c2
-rw-r--r--lib/libc/stdio/vsscanf.c11
-rw-r--r--lib/libc/stdio/xprintf_time.c3
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;
OpenPOWER on IntegriCloud