summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2011-05-29 02:53:52 +0000
committerhrs <hrs@FreeBSD.org>2011-05-29 02:53:52 +0000
commit8fe640108653f13042f1b15213769e338aa524f6 (patch)
tree91f5675a7c792e61d68635707501027daa3f566f /lib/libc/stdio
parent97f64b711efa9ff0011bef5d46cf9645638a38f9 (diff)
parentf3726238c8e8206eb1df4cfaf3f00947ceba3cce (diff)
downloadFreeBSD-src-8fe640108653f13042f1b15213769e338aa524f6.zip
FreeBSD-src-8fe640108653f13042f1b15213769e338aa524f6.tar.gz
Merge from head@222434.
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r--lib/libc/stdio/fgets.326
-rw-r--r--lib/libc/stdio/findfp.c5
-rw-r--r--lib/libc/stdio/fopen.34
-rw-r--r--lib/libc/stdio/freopen.c21
-rw-r--r--lib/libc/stdio/getline.328
-rw-r--r--lib/libc/stdio/local.h8
-rw-r--r--lib/libc/stdio/printf-pos.c6
-rw-r--r--lib/libc/stdio/printf.3152
-rw-r--r--lib/libc/stdio/snprintf.c5
-rw-r--r--lib/libc/stdio/tmpnam.322
-rw-r--r--lib/libc/stdio/vasprintf.c12
-rw-r--r--lib/libc/stdio/vdprintf.c4
-rw-r--r--lib/libc/stdio/vfprintf.c2
-rw-r--r--lib/libc/stdio/vsnprintf.c5
-rw-r--r--lib/libc/stdio/vsprintf.c5
-rw-r--r--lib/libc/stdio/vsscanf.c7
-rw-r--r--lib/libc/stdio/vswprintf.c5
-rw-r--r--lib/libc/stdio/vswscanf.c7
-rw-r--r--lib/libc/stdio/wprintf.310
-rw-r--r--lib/libc/stdio/xprintf.c3
-rw-r--r--lib/libc/stdio/xprintf_time.c24
21 files changed, 169 insertions, 192 deletions
diff --git a/lib/libc/stdio/fgets.3 b/lib/libc/stdio/fgets.3
index aa8e2ac..fba7353 100644
--- a/lib/libc/stdio/fgets.3
+++ b/lib/libc/stdio/fgets.3
@@ -128,6 +128,19 @@ may also fail and set
.Va errno
for any of the errors specified for the routine
.Xr getchar 3 .
+.Sh SEE ALSO
+.Xr feof 3 ,
+.Xr ferror 3 ,
+.Xr fgetln 3 ,
+.Xr fgetws 3 ,
+.Xr getline 3
+.Sh STANDARDS
+The functions
+.Fn fgets
+and
+.Fn gets
+conform to
+.St -isoC-99 .
.Sh SECURITY CONSIDERATIONS
The
.Fn gets
@@ -143,16 +156,3 @@ It is strongly suggested that the
function be used in all cases.
(See
the FSA.)
-.Sh SEE ALSO
-.Xr feof 3 ,
-.Xr ferror 3 ,
-.Xr fgetln 3 ,
-.Xr fgetws 3 ,
-.Xr getline 3
-.Sh STANDARDS
-The functions
-.Fn fgets
-and
-.Fn gets
-conform to
-.St -isoC-99 .
diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c
index 5bc4af7..89c0536 100644
--- a/lib/libc/stdio/findfp.c
+++ b/lib/libc/stdio/findfp.c
@@ -61,6 +61,7 @@ int __sdidinit;
._read = __sread, \
._seek = __sseek, \
._write = __swrite, \
+ ._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \
}
/* the usual - (stdin + stdout + stderr) */
static FILE usual[FOPEN_MAX - 3];
@@ -96,7 +97,7 @@ moreglue(n)
int n;
{
struct glue *g;
- static FILE empty;
+ static FILE empty = { ._fl_mutex = PTHREAD_MUTEX_INITIALIZER };
FILE *p;
g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE));
@@ -154,7 +155,7 @@ found:
fp->_ub._size = 0;
fp->_lb._base = NULL; /* no line buffer */
fp->_lb._size = 0;
-/* fp->_lock = NULL; */ /* once set always set (reused) */
+/* fp->_fl_mutex = NULL; */ /* once set always set (reused) */
fp->_orientation = 0;
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
return (fp);
diff --git a/lib/libc/stdio/fopen.3 b/lib/libc/stdio/fopen.3
index 92ec1e2..5c1f2b1 100644
--- a/lib/libc/stdio/fopen.3
+++ b/lib/libc/stdio/fopen.3
@@ -104,7 +104,7 @@ This is strictly for compatibility with
and has no effect; the ``b'' is ignored.
.Pp
Any created files will have mode
-.Pf \\*q Dv S_IRUSR
+.Do Dv S_IRUSR
\&|
.Dv S_IWUSR
\&|
@@ -114,7 +114,7 @@ Any created files will have mode
\&|
.Dv S_IROTH
\&|
-.Dv S_IWOTH Ns \\*q
+.Dv S_IWOTH Dc
.Pq Li 0666 ,
as modified by the process'
umask value (see
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
index d718496..be7bc8a 100644
--- a/lib/libc/stdio/freopen.c
+++ b/lib/libc/stdio/freopen.c
@@ -150,14 +150,6 @@ freopen(file, mode, fp)
/* Get a new descriptor to refer to the new file. */
f = _open(file, oflags, DEFFILEMODE);
- if (f < 0 && isopen) {
- /* If out of fd's close the old one and try again. */
- if (errno == ENFILE || errno == EMFILE) {
- (void) (*fp->_close)(fp->_cookie);
- isopen = 0;
- f = _open(file, oflags, DEFFILEMODE);
- }
- }
sverrno = errno;
finish:
@@ -165,9 +157,11 @@ finish:
* Finish closing fp. Even if the open succeeded above, we cannot
* keep fp->_base: it may be the wrong size. This loses the effect
* of any setbuffer calls, but stdio has always done this before.
+ *
+ * Leave the existing file descriptor open until dup2() is called
+ * below to avoid races where a concurrent open() in another thread
+ * could claim the existing descriptor.
*/
- if (isopen)
- (void) (*fp->_close)(fp->_cookie);
if (fp->_flags & __SMBF)
free((char *)fp->_bf._base);
fp->_w = 0;
@@ -186,6 +180,8 @@ finish:
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
if (f < 0) { /* did not get it after all */
+ if (isopen)
+ (void) (*fp->_close)(fp->_cookie);
fp->_flags = 0; /* set it free */
FUNLOCKFILE(fp);
errno = sverrno; /* restore in case _close clobbered */
@@ -197,11 +193,12 @@ finish:
* to maintain the descriptor. Various C library routines (perror)
* assume stderr is always fd STDERR_FILENO, even if being freopen'd.
*/
- if (wantfd >= 0 && f != wantfd) {
+ if (wantfd >= 0) {
if (_dup2(f, wantfd) >= 0) {
(void)_close(f);
f = wantfd;
- }
+ } else
+ (void)_close(fp->_file);
}
/*
diff --git a/lib/libc/stdio/getline.3 b/lib/libc/stdio/getline.3
index a5b39da..e0dda08 100644
--- a/lib/libc/stdio/getline.3
+++ b/lib/libc/stdio/getline.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 29, 2009
+.Dd November 30, 2010
.Dt GETLINE 3
.Os
.Sh NAME
@@ -54,23 +54,23 @@ function is equivalent to
with the newline character as the delimiter.
The delimiter character is included as part of the line, unless
the end of the file is reached.
-The caller may provide a pointer to a malloc buffer for the line in
+.Pp
+The caller may provide a pointer to a malloced buffer for the line in
.Fa *linep ,
and the capacity of that buffer in
-.Fa *linecapp ;
-if
-.Fa *linecapp
-is 0, then
-.Fa *linep
-is treated as
-.Dv NULL .
-These functions may expand the buffer as needed, as if via
-.Fn realloc ,
-and update
+.Fa *linecapp .
+These functions expand the buffer as needed, as if via
+.Fn realloc .
+If
+.Fa linep
+points to a
+.Dv NULL
+pointer, a new buffer will be allocated.
+In either case,
.Fa *linep
and
.Fa *linecapp
-accordingly.
+will be updated accordingly.
.Sh RETURN VALUES
The
.Fn getdelim
@@ -140,7 +140,7 @@ No delimiter was found in the first
characters.
.El
.Pp
-These functions may also fail for any of the errors specified for
+These functions may also fail due to any of the errors specified for
.Fn fgets
and
.Fn malloc .
diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h
index 09b3a18..6380b83 100644
--- a/lib/libc/stdio/local.h
+++ b/lib/libc/stdio/local.h
@@ -110,6 +110,14 @@ extern int __sdidinit;
}
/*
+ * Structure initializations for 'fake' FILE objects.
+ */
+#define FAKE_FILE { \
+ ._file = -1, \
+ ._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \
+}
+
+/*
* Set the orientation for a stream. If o > 0, the stream has wide-
* orientation. If o < 0, the stream has byte-orientation.
*/
diff --git a/lib/libc/stdio/printf-pos.c b/lib/libc/stdio/printf-pos.c
index 1648957..c42bd85 100644
--- a/lib/libc/stdio/printf-pos.c
+++ b/lib/libc/stdio/printf-pos.c
@@ -248,7 +248,6 @@ __find_arguments (const char *fmt0, va_list ap, union arg **argtable)
int n; /* handy integer (short term usage) */
int error;
int flags; /* flags as above */
- int width; /* width from format (%8d), or 0 */
struct typetable types; /* table of types */
fmt = (char *)fmt0;
@@ -266,7 +265,6 @@ __find_arguments (const char *fmt0, va_list ap, union arg **argtable)
fmt++; /* skip over '%' */
flags = 0;
- width = 0;
rflag: ch = *fmt++;
reswitch: switch (ch) {
@@ -304,7 +302,6 @@ reswitch: switch (ch) {
types.nextarg = n;
goto rflag;
}
- width = n;
goto reswitch;
#ifndef NO_FLOATING_POINT
case 'L':
@@ -439,7 +436,6 @@ __find_warguments (const wchar_t *fmt0, va_list ap, union arg **argtable)
int n; /* handy integer (short term usage) */
int error;
int flags; /* flags as above */
- int width; /* width from format (%8d), or 0 */
struct typetable types; /* table of types */
fmt = (wchar_t *)fmt0;
@@ -457,7 +453,6 @@ __find_warguments (const wchar_t *fmt0, va_list ap, union arg **argtable)
fmt++; /* skip over '%' */
flags = 0;
- width = 0;
rflag: ch = *fmt++;
reswitch: switch (ch) {
@@ -495,7 +490,6 @@ reswitch: switch (ch) {
types.nextarg = n;
goto rflag;
}
- width = n;
goto reswitch;
#ifndef NO_FLOATING_POINT
case 'L':
diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3
index 8de2bb8..90a8ed8 100644
--- a/lib/libc/stdio/printf.3
+++ b/lib/libc/stdio/printf.3
@@ -449,7 +449,7 @@ The
.Vt double
argument is rounded and converted in the style
.Sm off
-.Oo \- Oc Ar d Li \&. Ar ddd Li e \\*[Pm] Ar dd
+.Oo \- Oc Ar d Li \&. Ar ddd Li e \(+- Ar dd
.Sm on
where there is one digit before the
decimal-point character
@@ -525,7 +525,7 @@ The
.Vt double
argument is rounded and converted to hexadecimal notation in the style
.Sm off
-.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d ,
+.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \(+- Oc Ar d ,
.Sm on
where the number of digits after the hexadecimal-point character
is equal to the precision specification.
@@ -709,77 +709,6 @@ char *newfmt(const char *fmt, ...)
return (p);
}
.Ed
-.Sh SECURITY CONSIDERATIONS
-The
-.Fn sprintf
-and
-.Fn vsprintf
-functions are easily misused in a manner which enables malicious users
-to arbitrarily change a running program's functionality through
-a buffer overflow attack.
-Because
-.Fn sprintf
-and
-.Fn vsprintf
-assume an infinitely long string,
-callers must be careful not to overflow the actual space;
-this is often hard to assure.
-For safety, programmers should use the
-.Fn snprintf
-interface instead.
-For example:
-.Bd -literal
-void
-foo(const char *arbitrary_string, const char *and_another)
-{
- char onstack[8];
-
-#ifdef BAD
- /*
- * This first sprintf is bad behavior. Do not use sprintf!
- */
- sprintf(onstack, "%s, %s", arbitrary_string, and_another);
-#else
- /*
- * The following two lines demonstrate better use of
- * snprintf().
- */
- snprintf(onstack, sizeof(onstack), "%s, %s", arbitrary_string,
- and_another);
-#endif
-}
-.Ed
-.Pp
-The
-.Fn printf
-and
-.Fn sprintf
-family of functions are also easily misused in a manner
-allowing malicious users to arbitrarily change a running program's
-functionality by either causing the program
-to print potentially sensitive data
-.Dq "left on the stack" ,
-or causing it to generate a memory fault or bus error
-by dereferencing an invalid pointer.
-.Pp
-.Cm %n
-can be used to write arbitrary data to potentially carefully-selected
-addresses.
-Programmers are therefore strongly advised to never pass untrusted strings
-as the
-.Fa format
-argument, as an attacker can put format specifiers in the string
-to mangle your stack,
-leading to a possible security hole.
-This holds true even if the string was built using a function like
-.Fn snprintf ,
-as the resulting string may still contain user-supplied conversion specifiers
-for later interpolation by
-.Fn printf .
-.Pp
-Always use the proper secure idiom:
-.Pp
-.Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);"
.Sh COMPATIBILITY
Many application writers used the name
.Va dprintf
@@ -891,9 +820,9 @@ in
.Fx 2.2 ,
but were later replaced with a different implementation
from
-.An Todd C. Miller Aq Todd.Miller@courtesan.com
-for
-.Ox 2.3 .
+.Ox 2.3
+by
+.An Todd C. Miller Aq Todd.Miller@courtesan.com .
The
.Fn dprintf
and
@@ -906,3 +835,74 @@ The
family of functions do not correctly handle multibyte characters in the
.Fa format
argument.
+.Sh SECURITY CONSIDERATIONS
+The
+.Fn sprintf
+and
+.Fn vsprintf
+functions are easily misused in a manner which enables malicious users
+to arbitrarily change a running program's functionality through
+a buffer overflow attack.
+Because
+.Fn sprintf
+and
+.Fn vsprintf
+assume an infinitely long string,
+callers must be careful not to overflow the actual space;
+this is often hard to assure.
+For safety, programmers should use the
+.Fn snprintf
+interface instead.
+For example:
+.Bd -literal
+void
+foo(const char *arbitrary_string, const char *and_another)
+{
+ char onstack[8];
+
+#ifdef BAD
+ /*
+ * This first sprintf is bad behavior. Do not use sprintf!
+ */
+ sprintf(onstack, "%s, %s", arbitrary_string, and_another);
+#else
+ /*
+ * The following two lines demonstrate better use of
+ * snprintf().
+ */
+ snprintf(onstack, sizeof(onstack), "%s, %s", arbitrary_string,
+ and_another);
+#endif
+}
+.Ed
+.Pp
+The
+.Fn printf
+and
+.Fn sprintf
+family of functions are also easily misused in a manner
+allowing malicious users to arbitrarily change a running program's
+functionality by either causing the program
+to print potentially sensitive data
+.Dq "left on the stack" ,
+or causing it to generate a memory fault or bus error
+by dereferencing an invalid pointer.
+.Pp
+.Cm %n
+can be used to write arbitrary data to potentially carefully-selected
+addresses.
+Programmers are therefore strongly advised to never pass untrusted strings
+as the
+.Fa format
+argument, as an attacker can put format specifiers in the string
+to mangle your stack,
+leading to a possible security hole.
+This holds true even if the string was built using a function like
+.Fn snprintf ,
+as the resulting string may still contain user-supplied conversion specifiers
+for later interpolation by
+.Fn printf .
+.Pp
+Always use the proper secure idiom:
+.Pp
+.Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);"
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
index 0470a33..e6d7115 100644
--- a/lib/libc/stdio/snprintf.c
+++ b/lib/libc/stdio/snprintf.c
@@ -48,7 +48,7 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...)
size_t on;
int ret;
va_list ap;
- FILE f;
+ FILE f = FAKE_FILE;
on = n;
if (n != 0)
@@ -56,12 +56,9 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...)
if (n > INT_MAX)
n = INT_MAX;
va_start(ap, fmt);
- f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n;
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfprintf(&f, fmt, ap);
if (on > 0)
*f._p = '\0';
diff --git a/lib/libc/stdio/tmpnam.3 b/lib/libc/stdio/tmpnam.3
index 66652b7..937068f 100644
--- a/lib/libc/stdio/tmpnam.3
+++ b/lib/libc/stdio/tmpnam.3
@@ -217,6 +217,17 @@ for any of the errors specified for the library functions
.Xr malloc 3
or
.Xr mktemp 3 .
+.Sh SEE ALSO
+.Xr mkstemp 3 ,
+.Xr mktemp 3
+.Sh STANDARDS
+The
+.Fn tmpfile
+and
+.Fn tmpnam
+functions
+conform to
+.St -isoC .
.Sh SECURITY CONSIDERATIONS
The
.Fn tmpnam
@@ -235,14 +246,3 @@ It is strongly suggested that
be used in place of these functions.
(See
the FSA.)
-.Sh SEE ALSO
-.Xr mkstemp 3 ,
-.Xr mktemp 3
-.Sh STANDARDS
-The
-.Fn tmpfile
-and
-.Fn tmpnam
-functions
-conform to
-.St -isoC .
diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c
index 0682b5b..a1b600a 100644
--- a/lib/libc/stdio/vasprintf.c
+++ b/lib/libc/stdio/vasprintf.c
@@ -36,25 +36,19 @@ __FBSDID("$FreeBSD$");
#include "local.h"
int
-vasprintf(str, fmt, ap)
- char **str;
- const char *fmt;
- __va_list ap;
+vasprintf(char **str, const char *fmt, __va_list ap)
{
+ FILE f = FAKE_FILE;
int ret;
- FILE f;
- f._file = -1;
f._flags = __SWR | __SSTR | __SALC;
- f._bf._base = f._p = (unsigned char *)malloc(128);
+ f._bf._base = f._p = malloc(128);
if (f._bf._base == NULL) {
*str = NULL;
errno = ENOMEM;
return (-1);
}
f._bf._size = f._w = 127; /* Leave room for the NUL */
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfprintf(&f, fmt, ap);
if (ret < 0) {
free(f._bf._base);
diff --git a/lib/libc/stdio/vdprintf.c b/lib/libc/stdio/vdprintf.c
index 2703022..3ad273e 100644
--- a/lib/libc/stdio/vdprintf.c
+++ b/lib/libc/stdio/vdprintf.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
int
vdprintf(int fd, const char * __restrict fmt, va_list ap)
{
- FILE f;
+ FILE f = FAKE_FILE;
unsigned char buf[BUFSIZ];
int ret;
@@ -56,8 +56,6 @@ vdprintf(int fd, const char * __restrict fmt, va_list ap)
f._write = __swrite;
f._bf._base = buf;
f._bf._size = sizeof(buf);
- f._orientation = 0;
- bzero(&f._mbstate, sizeof(f._mbstate));
if ((ret = __vfprintf(&f, fmt, ap)) < 0)
return (ret);
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 7e5d7fe..17ad824 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -169,7 +169,7 @@ static int
__sbprintf(FILE *fp, const char *fmt, va_list ap)
{
int ret;
- FILE fake;
+ FILE fake = FAKE_FILE;
unsigned char buf[BUFSIZ];
/* XXX This is probably not needed. */
diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c
index f990664..70e4c53 100644
--- a/lib/libc/stdio/vsnprintf.c
+++ b/lib/libc/stdio/vsnprintf.c
@@ -47,7 +47,7 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
size_t on;
int ret;
char dummy[2];
- FILE f;
+ FILE f = FAKE_FILE;
on = n;
if (n != 0)
@@ -61,12 +61,9 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
str = dummy;
n = 1;
}
- f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n;
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfprintf(&f, fmt, ap);
if (on > 0)
*f._p = '\0';
diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c
index 60d830c..3890af7 100644
--- a/lib/libc/stdio/vsprintf.c
+++ b/lib/libc/stdio/vsprintf.c
@@ -44,14 +44,11 @@ int
vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap)
{
int ret;
- FILE f;
+ FILE f = FAKE_FILE;
- 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));
ret = __vfprintf(&f, fmt, ap);
*f._p = 0;
return (ret);
diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c
index 22b5d2b..82429c6 100644
--- a/lib/libc/stdio/vsscanf.c
+++ b/lib/libc/stdio/vsscanf.c
@@ -55,16 +55,11 @@ int
vsscanf(const char * __restrict str, const char * __restrict fmt,
__va_list ap)
{
- FILE f;
+ FILE f = FAKE_FILE;
- 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));
return (__svfscanf(&f, fmt, ap));
}
diff --git a/lib/libc/stdio/vswprintf.c b/lib/libc/stdio/vswprintf.c
index 61b8720..2cfe724 100644
--- a/lib/libc/stdio/vswprintf.c
+++ b/lib/libc/stdio/vswprintf.c
@@ -45,7 +45,7 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
{
static const mbstate_t initial;
mbstate_t mbs;
- FILE f;
+ FILE f = FAKE_FILE;
char *mbp;
int ret, sverrno;
size_t nwc;
@@ -55,7 +55,6 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
return (-1);
}
- f._file = -1;
f._flags = __SWR | __SSTR | __SALC;
f._bf._base = f._p = (unsigned char *)malloc(128);
if (f._bf._base == NULL) {
@@ -63,8 +62,6 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
return (-1);
}
f._bf._size = f._w = 127; /* Leave room for the NUL */
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfwprintf(&f, fmt, ap);
if (ret < 0) {
sverrno = errno;
diff --git a/lib/libc/stdio/vswscanf.c b/lib/libc/stdio/vswscanf.c
index 8a70d44..f06fc02 100644
--- a/lib/libc/stdio/vswscanf.c
+++ b/lib/libc/stdio/vswscanf.c
@@ -62,7 +62,7 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
{
static const mbstate_t initial;
mbstate_t mbs;
- FILE f;
+ FILE f = FAKE_FILE;
char *mbstr;
size_t mlen;
int r;
@@ -80,15 +80,10 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
free(mbstr);
return (EOF);
}
- f._file = -1;
f._flags = __SRD;
f._bf._base = f._p = (unsigned char *)mbstr;
f._bf._size = f._r = mlen;
f._read = eofread;
- f._ub._base = NULL;
- f._lb._base = NULL;
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
r = __vfwscanf(&f, fmt, ap);
free(mbstr);
diff --git a/lib/libc/stdio/wprintf.3 b/lib/libc/stdio/wprintf.3
index d9e724f..fecb586 100644
--- a/lib/libc/stdio/wprintf.3
+++ b/lib/libc/stdio/wprintf.3
@@ -376,7 +376,7 @@ The
.Vt double
argument is rounded and converted in the style
.Sm off
-.Oo \- Oc Ar d Li \&. Ar ddd Li e \\*[Pm] Ar dd
+.Oo \- Oc Ar d Li \&. Ar ddd Li e \(+- Ar dd
.Sm on
where there is one digit before the
decimal-point character
@@ -452,7 +452,7 @@ The
.Vt double
argument is converted to hexadecimal notation in the style
.Sm off
-.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d ,
+.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \(+- Oc Ar d ,
.Sm on
where the number of digits after the hexadecimal-point character
is equal to the precision specification.
@@ -588,9 +588,6 @@ In no case does a non-existent or small field width cause truncation of
a numeric field; if the result of a conversion is wider than the field
width, the
field is expanded to contain the conversion result.
-.Sh SECURITY CONSIDERATIONS
-Refer to
-.Xr printf 3 .
.Sh SEE ALSO
.Xr btowc 3 ,
.Xr fputws 3 ,
@@ -616,3 +613,6 @@ and
functions
conform to
.St -isoC-99 .
+.Sh SECURITY CONSIDERATIONS
+Refer to
+.Xr printf 3 .
diff --git a/lib/libc/stdio/xprintf.c b/lib/libc/stdio/xprintf.c
index bb41a9c..0cc8571 100644
--- a/lib/libc/stdio/xprintf.c
+++ b/lib/libc/stdio/xprintf.c
@@ -48,6 +48,7 @@
#include <wchar.h>
#include "un-namespace.h"
+#include "local.h"
#include "printf.h"
#include "fvwrite.h"
@@ -575,7 +576,7 @@ static int
__v3printf(FILE *fp, const char *fmt, int pct, va_list ap)
{
int ret;
- FILE fake;
+ FILE fake = FAKE_FILE;
unsigned char buf[BUFSIZ];
/* copy the important variables */
diff --git a/lib/libc/stdio/xprintf_time.c b/lib/libc/stdio/xprintf_time.c
index 9d732fe..debfac5 100644
--- a/lib/libc/stdio/xprintf_time.c
+++ b/lib/libc/stdio/xprintf_time.c
@@ -62,7 +62,7 @@ __printf_render_time(struct __printf_io *io, const struct printf_info *pi, const
struct timespec *ts;
time_t *tp;
intmax_t t, tx;
- int i, prec, nsec;
+ int i, prec, nsec, ret;
if (pi->is_long) {
tv = *((struct timeval **)arg[0]);
@@ -80,6 +80,12 @@ __printf_render_time(struct __printf_io *io, const struct printf_info *pi, const
nsec = 0;
prec = 0;
}
+ if (pi->is_long || pi->is_long_double) {
+ if (pi->prec >= 0)
+ prec = pi->prec;
+ if (prec == 0)
+ nsec = 0;
+ }
p = buf;
if (pi->alt) {
@@ -88,29 +94,29 @@ __printf_render_time(struct __printf_io *io, const struct printf_info *pi, const
p += sprintf(p, "%jdy", t / YEAR);
t %= YEAR;
}
- if (t >= DAY && t != 0) {
+ if (tx >= DAY && (t != 0 || prec != 0)) {
p += sprintf(p, "%jdd", t / DAY);
t %= DAY;
}
- if (t >= HOUR && t != 0) {
+ if (tx >= HOUR && (t != 0 || prec != 0)) {
p += sprintf(p, "%jdh", t / HOUR);
t %= HOUR;
}
- if (t >= MINUTE && t != 0) {
+ if (tx >= MINUTE && (t != 0 || prec != 0)) {
p += sprintf(p, "%jdm", t / MINUTE);
t %= MINUTE;
}
- if (t != 0 || tx == 0)
+ if (t != 0 || tx == 0 || prec != 0)
p += sprintf(p, "%jds", t);
} else {
p += sprintf(p, "%jd", (intmax_t)t);
}
- if (pi->is_long || pi->is_long_double) {
- if (pi->prec >= 0)
- prec = pi->prec;
+ if (prec != 0) {
for (i = prec; i < 9; i++)
nsec /= 10;
p += sprintf(p, ".%.*d", prec, nsec);
}
- return(__printf_out(io, pi, buf, p - buf));
+ ret = __printf_out(io, pi, buf, p - buf);
+ __printf_flush(io);
+ return (ret);
}
OpenPOWER on IntegriCloud