about summary refs log tree commit diff
path: root/src/stdio/vfprintf.c
Commit message (Collapse)AuthorAgeFilesLines
* clean up stdio_impl.hRich Felker2012-11-081-0/+9
| | | | | | | | | | | this header evolved to facilitate the extremely lazy practice of omitting explicit includes of the necessary headers in individual stdio source files; not only was this sloppy, but it also increased build time. now, stdio_impl.h is only including the headers it needs for its own use; any further headers needed by source files are included directly where needed.
* avoid raising spurious division-by-zero exception in printfRich Felker2012-10-181-1/+1
|
* use restrict everywhere it's required by c99 and/or posix 2008Rich Felker2012-09-061-1/+1
| | | | | | | | to deal with the fact that the public headers may be used with pre-c99 compilers, __restrict is used in place of restrict, and defined appropriately for any supported compiler. we also avoid the form [restrict] since older versions of gcc rejected it due to a bug in the original c99 standard, and instead use the form *restrict.
* minor but worthwhile optimization in printf: avoid expensive strspnRich Felker2012-08-101-4/+2
| | | | | | the strspn call was made for every format specifier and end-of-string, even though the expected return value was 1-2 for normal usage. replace with simple loop.
* fix another oob pointer arithmetic issue in printf floating pointRich Felker2012-06-201-1/+1
| | | | | | this one could never cause any problems unless the compiler/machine goes to extra trouble to break oob pointer arithmetic, but it's best to fix it anyway.
* fix pointer overflow bug in floating point printfRich Felker2012-06-191-3/+3
| | | | | | | | | | | | | | | | | | | | | large precision values could cause out-of-bounds pointer arithmetic in computing the precision cutoff (used to avoid expensive long-precision arithmetic when the result will be discarded). per the C standard, this is undefined behavior. one would expect that it works anyway, and in fact it did in most real-world cases, but it was randomly (depending on aslr) crashing in i386 binaries running on x86_64 kernels. this is because linux puts the userspace stack near 4GB (instead of near 3GB) when the kernel is 64-bit, leading to the out-of-bounds pointer arithmetic overflowing past the end of address space and giving a very low pointer value, which then compared lower than a pointer it should have been higher than. the new code rearranges the arithmetic so that no overflow can occur. while this bug could crash printf with memory corruption, it's unlikely to have security impact in real-world applications since the ability to provide an extremely large field precision value under attacker-control is required to trigger the bug.
* fix %ls breakage in last printf fixRich Felker2012-06-081-2/+2
| | | | signedness issue kept %ls with no precision from working at all
* fix printf %ls with precision limit over-read issueRich Felker2012-06-081-2/+2
| | | | | | | printf was not printing too many characters, but it was reading one too many wchar_t elements from the input. this could lead to crashes if running off the page, or spurious failure if the conversion of the extra wchar_t resulted in EILSEQ.
* fix buffer overflow in vfprintf on long writes to unbuffered filesRich Felker2012-04-171-1/+2
| | | | | | | | | | | | | | | | | | vfprintf temporarily swaps in a local buffer (for the duration of the operation) when the target stream is unbuffered; this both simplifies the implementation of functions like dprintf (they don't need their own buffers) and eliminates the pathologically bad performance of writing the formatted output with one or more write syscalls per formatting field. in cases like dprintf where we are dealing with a virgin FILE structure, everything worked correctly. however for long-lived files (like stderr), it's possible that the buffer bounds were already set for the internal zero-size buffer. on the next write, __stdio_write would pick up and use the new buffer provided by vfprintf, but the bound (wend) field was still pointing at the internal zero-size buffer's end. this in turn allowed unbounded writes to the temporary buffer.
* fix %lf, etc. with printfRich Felker2012-04-161-0/+2
| | | | | | the l prefix is redundant/no-op with printf, since default promotions always promote floats to double; however, it is valid, and printf was wrongly rejecting it.
* don't crash on null strings in printfRich Felker2011-09-281-1/+1
| | | | passing null pointer for %s is UB but lots of broken programs do it anyway
* printf: "if a precision is specified, the '0' flag shall be ignored."Rich Felker2011-07-041-1/+1
|
* zero precision with zero value should not inhibit prefix/width printingRich Felker2011-07-041-1/+4
|
* printf("%#x",0) should print 0 not 0x0Rich Felker2011-07-041-1/+1
|
* fix the last known rounding bug in floating point printingRich Felker2011-05-111-3/+4
| | | | | | | | | the observed symptom was that the code was incorrectly rounding up 1.0625 to 1.063 despite the rounding mode being round-to-nearest with ties broken by rounding to even last place. however, the code was just not right in many respects, and i'm surprised it worked as well as it did. this time i tested the values that end up in the variables round, small, and the expression round+small, and all look good.
* fix printf("%.9g", 1.1) and similar not dropping trailing zerosRich Felker2011-04-121-1/+3
|
* fix overflow in printf %N$ argument handlingRich Felker2011-04-051-2/+2
|
* fix various floating point rounding and formatting errors in *printfRich Felker2011-04-051-17/+25
|
* use a local temp buffer for unbuffered streams in vfprintfRich Felker2011-04-041-0/+13
| | | | | | | | | this change makes it so most calls to fprintf(stderr, ...) will result in a single writev syscall, as opposed to roughly 2*N syscalls (and possibly more) where N is the number of format specifiers. in principle we could use a much larger buffer, but it's best not to increase the stack requirements too much. most messages are under 80 chars.
* major stdio overhaul, using readv/writev, plus other changesRich Felker2011-03-281-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | the biggest change in this commit is that stdio now uses readv to fill the caller's buffer and the FILE buffer with a single syscall, and likewise writev to flush the FILE buffer and write out the caller's buffer in a single syscall. making this change required fundamental architectural changes to stdio, so i also made a number of other improvements in the process: - the implementation no longer assumes that further io will fail following errors, and no longer blocks io when the error flag is set (though the latter could easily be changed back if desired) - unbuffered mode is no longer implemented as a one-byte buffer. as a consequence, scanf unreading has to use ungetc, to the unget buffer has been enlarged to hold at least 2 wide characters. - the FILE structure has been rearranged to maintain the locations of the fields that might be used in glibc getc/putc type macros, while shrinking the structure to save some space. - error cases for fflush, fseek, etc. should be more correct. - library-internal macros are used for getc_unlocked and putc_unlocked now, eliminating some ugly code duplication. __uflow and __overflow are no longer used anywhere but these macros. switch to read or write mode is also separated so the code can be better shared, e.g. with ungetc. - lots of other small things.
* fix all implicit conversion between signed/unsigned pointersRich Felker2011-03-251-1/+1
| | | | | | | sadly the C language does not specify any such implicit conversion, so this is not a matter of just fixing warnings (as gcc treats it) but actual errors. i would like to revisit a number of these changes and possibly revise the types used to reduce the number of casts required.
* fix %n specifier, again. this time it was storing the wrong value.Rich Felker2011-02-201-7/+7
|
* fix printf %n specifier - missing breaks had it clobbering memoryRich Felker2011-02-161-7/+7
|
* initial check-in, version 0.5.0 v0.5.0Rich Felker2011-02-121-0/+640