diff options
author | hrs <hrs@FreeBSD.org> | 2011-05-29 02:53:52 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2011-05-29 02:53:52 +0000 |
commit | 8fe640108653f13042f1b15213769e338aa524f6 (patch) | |
tree | 91f5675a7c792e61d68635707501027daa3f566f /lib/libc/stdio | |
parent | 97f64b711efa9ff0011bef5d46cf9645638a38f9 (diff) | |
parent | f3726238c8e8206eb1df4cfaf3f00947ceba3cce (diff) | |
download | FreeBSD-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.3 | 26 | ||||
-rw-r--r-- | lib/libc/stdio/findfp.c | 5 | ||||
-rw-r--r-- | lib/libc/stdio/fopen.3 | 4 | ||||
-rw-r--r-- | lib/libc/stdio/freopen.c | 21 | ||||
-rw-r--r-- | lib/libc/stdio/getline.3 | 28 | ||||
-rw-r--r-- | lib/libc/stdio/local.h | 8 | ||||
-rw-r--r-- | lib/libc/stdio/printf-pos.c | 6 | ||||
-rw-r--r-- | lib/libc/stdio/printf.3 | 152 | ||||
-rw-r--r-- | lib/libc/stdio/snprintf.c | 5 | ||||
-rw-r--r-- | lib/libc/stdio/tmpnam.3 | 22 | ||||
-rw-r--r-- | lib/libc/stdio/vasprintf.c | 12 | ||||
-rw-r--r-- | lib/libc/stdio/vdprintf.c | 4 | ||||
-rw-r--r-- | lib/libc/stdio/vfprintf.c | 2 | ||||
-rw-r--r-- | lib/libc/stdio/vsnprintf.c | 5 | ||||
-rw-r--r-- | lib/libc/stdio/vsprintf.c | 5 | ||||
-rw-r--r-- | lib/libc/stdio/vsscanf.c | 7 | ||||
-rw-r--r-- | lib/libc/stdio/vswprintf.c | 5 | ||||
-rw-r--r-- | lib/libc/stdio/vswscanf.c | 7 | ||||
-rw-r--r-- | lib/libc/stdio/wprintf.3 | 10 | ||||
-rw-r--r-- | lib/libc/stdio/xprintf.c | 3 | ||||
-rw-r--r-- | lib/libc/stdio/xprintf_time.c | 24 |
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); } |