So far, the printf family of functions has two output helper functions
called __sprint_r and __sfputs_r. Both are called from all variants of
vfprintf as well as vfwprintf. There are also analogue helper functions
for the string-creating functions vsprintf/vswprintf called __ssprint_r
and __ssputs_r.
However, the helpers are built once when building vfprintf/vsprintf with
the INTEGER_ONLY flag, and then they are part of the vfiprintf.c and
vsiprintf.c files.
The problem is this:
Even if a process only calls vfwprintf or the non-INTEGER_ONLY vfprintf
it will always have to include the INTEGER_ONLY vfiprintf. Otherwise the
helper functions are undefined. Analogue for the string-creating
functions.
That's a useless waste of space by including one (or two) big, unused
function, if newlib is linked in statically.
Create new files to define the printf output helpers separately and
split them into byte-oriented and wide-char-oriented functions. This
allows to link only the required functions.
Also, simplify the string output helpers and fix a potential (but
unlikely) buffer overflow in __ssprint_r.
Fixes: 8a0efa53e4 ("import newlib-2000-02-17 snapshot")
Fixes: 6121968b19 ("* libc/include/stdio.h (__VALIST): Guard against multiple definition.")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Previously, fprintf() on a wide-oriented stream crashes or outputs
garbage. This is because a narrow char string which can be odd bytes
in length is cast into a wide char string which should be even
bytes in length in __sprint_r/__sfputs_r based on the __SWID flag.
As a result, if the length is odd bytes, the reading buffer runs over
the buffer length, which causes a crash. If the length is even bytes,
garbage is printed.
With this patch, any output to the stream which is set to different
orientation fails with error just like glibc. Note that it behaves
differently from other libc implementations such as BSD, musl and
Solaris.
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Add a _REENT_ERRNO() macro to encapsulate the access to the
_errno member of struct reent. This will help to replace the
structure member with a thread-local storage object in a follow
up patch.
Replace uses of __errno_r() with _REENT_ERRNO(). Keep __errno_r() macro for
potential users outside of Newlib.
- Currently, printf("%La\n", 1e1000L) crashes with segv due to lack
of frexpl() function. With this patch, frexpl() function has been
implemented in libm to solve this issue.
Addresses: https://sourceware.org/pipermail/newlib/2021/018718.html
Don't over-read memory returned by _DTOA_R, and never write to it
since the result might be a string literal.
For example, when doing:
swprintf(tt, 20, L"%.*f", 6, 0.0);
we will get back "0".
Instead, write the result returned by _DTOA_R to the output buffer.
After this, write the 0 chars directly to the the output buffer
(if there are any). This also has the (marginal) advantage that
we read/write less memory overall.
Move all locale category structure definitions into setlocale.h and remove
other headers in locale subdir. Create inline accessor functions for
current category struct pointers and use throughout. Use pointers to
"C" locale category structs by default in __global_locale.
Signed-off by: Corinna Vinschen <corinna@vinschen.de>
* newlib.hin (_FVWRITE_IN_STREAMIO): Undefine.
* configure.in (--disable-newlib-fvwrite-in-streamio): New option.
* configure: Regenerated.
* libc/stdio/fputs.c (_fputs_r): Use _FVWRITE_IN_STREAMIO to
control __sfvwrite_r. Add alternative implementation.
* libc/stdio/fputws.c (_fputws_r): Ditto.
* libc/stdio/fwrite.c (_fwrite_r): Ditto.
* libc/stdio/puts.c (_puts_r): Ditto.
* libc/stdio/vfprintf.c (__ssputs_r, __sfputs_r): New function.
(_VFPRINTF_R): Use _FVWRITE_IN_STREAMIO to control vector buffer.
(__SPRINT): Use _FVWRITE_IN_STREAMIO to control macro definition.
* libc/stdio/vfwprintf.c (_VFWPRINTF_R): Use _FVWRITE_IN_STREAMIO
to control vector buffer.
compiler warnings found this way.
* libc/stdio/freopen.c (_freopen_r): Fix bug setting _flags.
* libc/include/stdio.h (_rename): Define when building newlib.
* libc/include/sys/signal.h (_kill): Ditto.
* libc/include/sys/stat.h (_mkdir): Ditto.
* libc/include/sys/time.h (_gettimeofday): Ditto.
* libc/include/sys/times.h (_times): Ditto.
* libc/include/sys/wait.h (_wait): Ditto.
* libc/locale/lmessages.c (empty): Don't define for Cygwin.
* libc/locale/lmonetary.c (cnv): Ditto.
* libc/locale/nl_langinfo.c (nl_langinfo): Ditto for variable s.
* libc/posix/collate.c: Throughout cast to avoid compiler warning.
* libc/posix/engine.c (matcher): Initialize dp to avoid compiler
warning.
* libc/posix/glob.c: Disable on Cygwin. Explain why.
* libc/posix/regcomp.c: Fix "uninitialized" compiler warnings.
(dissect): Deliberately silence gcc compiler warning. Add comment to
explain why.
* libc/posix/wordexp.c (wordexp): Remove num_bytes variable since result
is never used.
* libc/posix/popen.c (popen): Ditto for variable last.
* libc/reent/mkdirr.c: Include sys/stat.h.
* libc/reent/renamer.c: Include stdio.h.
* libc/search/hash.c: Throughout use underscored variants of the stat
function family.
(init_hash): Add missing definition for the __USE_INTERNAL_STAT64 case.
* libc/search/hash_bigkey.c (__big_insert): Add parenthesis to avoid
compiler warning.
* libc/search/hash_page.c (overflow_page): Initalize freep to NULL to
avoid compiler warning.
* libc/stdio/asiprintf.c (_asiprintf_r): Cast unsigned char * to char *
to avoid compiler warning.
(asiprintf): Ditto.
* libc/stdio/asprintf.c (_asprintf_r): Ditto.
(asprintf): Ditto.
* libc/stdio/vasiprintf.c (_vasiprintf_r): Ditto.
* libc/stdio/vasprintf.c (_vasprintf_r): Ditto.
* libc/stdio/mktemp.c (_gettemp): Cast to unsigned char in call to
isdigit to avoid compiler warning.
* libc/stdio/vfprintf.c (_VFPRINTF_R): Initialize variables used for
grouping to avoid compiler warning. Only define and set nseps and
nrepeats if they are really used.
* libc/stdio/vfwprintf.c (_VFWPRINTF_R): Ditto. Only define state if
it is really used.
* libc/stdio/vfscanf.c (u_char): Revert to be defined as unsigned char.
(__SVFSCANF_R): Cast fmt in call to __mbtowc.
* libc/stdlib/mbtowc_r.c (JIS_state_table): Disable when building
Cygwin.
(JIS_action_table): Ditto.
* libc/stdlib/wctomb_r.c (__utf8_wctomb): Add parenthesis to avoid
compiler warning.
* libc/string/strcasestr.c: Deliberately silence gcc compiler warning.
Add comment to explain why.
* libc/time/strptime.c (strptime): Cast to unsigned char in calls to
isspace to avoid compiler warning.
* libm/math/e_atan2.c (__ieee754_atan2): Add parenthesis to avoid
compiler warning.
* libm/math/e_exp.c (__ieee754_exp): Initialize k to 0 to avoid
compiler warning. Drop setting it to 0 later.
* libm/math/ef_exp.c (__ieee754_expf): Ditto.
* libm/math/e_pow.c (__ieee754_pow): Add braces to avoid compiler
warning.
* libm/math/ef_pow.c (__ieee754_powf): Ditto.
* libm/math/er_lgamma.c (__ieee754_lgamma_r): Initialize nadj to 0 to
avoid compiler warning.
* libm/math/erf_lgamma.c (__ieee754_lgammaf_r): Ditto.
* libm/math/e_rem_pio2.c (__ieee754_rem_pio2): Ditto for variable z.
* libm/common/sf_round.c (roundf): Remove signbit variable since result
is never used.
secure stream related critical section against thread cancellation.
(_newlib_flockfile_exit): Ditto.
(_newlib_sfp_lock_end): Ditto.
(_newlib_sfp_lock_start): Ditto for the list of streams.
(_newlib_sfp_lock_exit): Ditto.
(_newlib_sfp_lock_end): Ditto.
Use aforementioned macros in place of _flockfile/_funlockfile
and __sfp_lock_acquire/__sfp_lock_release throughout the code.
* libc/stdio/fclose.c: Explicitely disable and re-enable thread
cancellation. Explain why.
* libc/stdio/freopen.c: Ditto.
* libc/stdio64/freopen64.c: Ditto.
* libc/stdio/vfwprintf.c (wcvt): Add a new parameter len of type
int. *length is set to the value of (rev - digits) regardless
of whether _MB_CAPABLE is defined or not. Replace BUF with len
in calling _mbsnrtowcs_r and also in the loop where _MB_CAPABLE
is not defined.
(_VFWPRINTF_R): Call wcvt with an extra argument. Call wcvt
again with allocated new buffer if buf is not large enough for
the conversion.
* testsuite/newlib.stdio/stdio.exp: New.
* testsuite/newlib.stdio/swprintf.c: Likewise.
if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
* libc/include/langinfo.h (enum __nl_item): New type. Define all
native values accessible through nl_langinfo. Define previously
existing POSIX-compatible values as macros as well.
* libc/include/stdlib.h (__mb_cur_max): Drop declaration.
(__locale_mb_cur_max): Declare.
(MB_CUR_MAX): Re-define calling __locale_mb_cur_max.
* libc/locale/Makefile.am (ELIX_SOURCES): Add lctype.c.
* libc/locale/Makefile.in: Regenerate.
* libc/locale/lctype.c: New file to define and load LC_CTYPE category.
* libc/locale/lctype.h: New file, matching header.
* libc/locale/lmessages.c (_C_messages_locale): Add default values for
wide char members.
(__messages_load_locale): Add _C_messages_locale in call to
__set_lc_messages_from_win.
* libc/locale/lmessages.h (struct lc_messages_T): Add wide char members.
* libc/locale/lmonetary.c (_C_monetary_locale): Add default values for
wide char members.
(__monetary_load_locale): Add _C_monetary_locale in call to
__set_lc_monetary_from_win.
* libc/locale/lmonetary.h (struct lc_monetary_T): Add wide char members.
Add numerical values for international currency formatting per
POSIX-1.2008, if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
* libc/locale/lnumeric.c (_C_numeric_locale): Add default values for
wide char members.
(__numeric_load_locale): Add _C_numeric_locale in call to
__set_lc_numeric_from_win.
* libc/locale/lnumeric.h (struct lc_numeric_T): Add wide char members.
* libc/locale/locale.c (loadlocale): Return doing nothing if category
locale didn't change. Convert category if chain to switch statement.
Call __ctype_load_locale in LC_CTYPE case.
(__locale_charset): Add (but disable for now) returning codeset from
__get_current_ctype_locale.
(__locale_mb_cur_max): Add (but disable for now) returning mb_cur_max
from __get_current_ctype_locale.
(__locale_msgcharset): Add returning codeset from
__get_current_messages_locale.
(_localeconv_r): Accommodate int_XXX values.
* libc/locale/nl_langinfo.c (nl_ext): New array to define what is to
be returned for non-POSIX values.
(nl_Langinfo): Return correct codeset for each locale category. Return
extended values if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
* libc/locale/timelocal.c (_C_time_locale): Add default values for
wide char members.
(__time_load_locale): Add _C_time_locale in call to
__set_lc_time_from_win.
* libc/locale/timelocal.h (struct lc_time_T): Add wide char members.
* libc/stdio/vfwprintf.c (_VFWPRINTF_R): Use wide char decimal point
and thousands_sep if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
* libc/time/strftime.c: Rework to accommodate availability of wide char
strings in LC_TIME category if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
is defined. Raise conversion buffer size to make sure it has enough
room for numbers plus grouping character. Define GROUPING flag.
(_VFPRINTF_R): Add PRINTANDPAD macro. Handle grouping flag character.
Handle grouping for decimal integer and float values.
* libc/stdio/vfwprintf.c: Ditto.
correct how terminating L'\0' is added;
change return to match standard for when output does not fit;
some corrections and enhancements to the docs.
* libc/stdio/vswprintf.c (_vswprintf_r): ditto, except for docs.
* libc/stdio/vfwprintf.c: some corrections to the docs and some
enhancements to comments. (No code changes.)
* libc/time/strftime.c: Correct some problems that made wcsftime()
not work correctly: work properly with swprintf returns that are
different from snprintf returns, correct test vector lengths for
when sizeof(wchar_t) > 1.
* libc/stdio/sprintf.c: Some documentation and comment corrections and
enhancements to match those done to swprintf.c.
* libc/include/wchar.h: Include stdarg.h.
(__VALIST): Define conditionally.
(fwprintf, swprintf, vfwprintf, vswprintf, vwprintf, wprintf: Declare.
(_fwprintf_r, _swprintf_r, _vfwprintf_r, _vswprintf_r, _vwprintf_r,
_wprintf_r): Declare.
* libc/stdio/Makefile.am: Add new files.
* libc/stdio/Makefile.in: Regenerate.
* libc/stdio/fwprintf.c: New file.
* libc/stdio/local.h (_svfwprintf_r, _svfiwprintf_r): Declare.
(__CH_CLASS, __STATE, __ACTION): Move definition from vfprintf.c here
and move to the __ namespace.
(__chclass, __state_table, __action_table): Declare.
* libc/stdio/stdio.tex: Add new documentation references.
* libc/stdio/swprintf.c: New file.
* libc/stdio/vfprintf.c (__SPRINT): New macro to call the right
__sprint_r function according to compilation unit. Use throughout.
(__ssprint_r): Rename STRING_ONLY variant from __sprint_r.
Make externaly available. Only define if INTEGER_ONLY is defined.
(__sprint_r): Make externaly available. Only define if INTEGER_ONLY
is defined. Handle stream orientation.
(__sbprintf): Copy FILE's _flags2 member as well.
(__chclass, __state_table, __action_table): Prepend __ to name and
make externally available.
* libc/stdio/vfwprintf.c: New file.
* libc/stdio/vswprintf.c: New file.
* libc/stdio/vwprintf.c: New file.
* libc/stdio/wprintf.c: New file.