diff options
author | Karl Williamson <khw@cpan.org> | 2023-01-12 17:31:24 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2023-02-10 15:35:49 -0700 |
commit | a683fa5b7e816ae5c10d246c9a0b1f3ea743274b (patch) | |
tree | cda0e5d3ef7599590f3b1f1edfea7894af56adce /util.c | |
parent | a170805d60a9631c88faf0da744391bfc8f2fe26 (diff) | |
download | perl-a683fa5b7e816ae5c10d246c9a0b1f3ea743274b.tar.gz |
snprintf() calls need to have proper radix
Calls to libc snprintf() were neglected to be changed when perl was
fixed to change the radix character to the proper one based on whether
or not 'use locale' is in effect. Perl-level code is unaffected, but
core and XS code is.
This commit changes to wrap snprintf() calls with the macros designed
for the purpose, long used for similar situations elsewhere in the code.
Doing this requires the thread context. I achieved this in a few places
by a dTHX, instead of assuming a caller would have the context already
available, and adding a pTHX_ parameter. I tried doing it the other
way, and got a few breakages in our test suite. Formatting already
requires significant CPU time, so this addition should just be in the
noise
This bug was found by new tests that will be added in a future commit.
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 52 |
1 files changed, 41 insertions, 11 deletions
@@ -5194,11 +5194,14 @@ getting C<vsnprintf>. =cut */ + int Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...) { int retval = -1; va_list ap; + dTHX; + PERL_ARGS_ASSERT_MY_SNPRINTF; #ifndef HAS_VSNPRINTF PERL_UNUSED_VAR(len); @@ -5207,9 +5210,12 @@ Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...) #ifdef USE_QUADMATH { bool quadmath_valid = FALSE; + if (quadmath_format_valid(format)) { /* If the format looked promising, use it as quadmath. */ - retval = quadmath_snprintf(buffer, len, format, va_arg(ap, NV)); + WITH_LC_NUMERIC_SET_TO_NEEDED( + retval = quadmath_snprintf(buffer, len, format, va_arg(ap, NV)); + ); if (retval == -1) { Perl_croak_nocontext("panic: quadmath_snprintf failed, format \"%s\"", format); } @@ -5241,12 +5247,20 @@ Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...) } #endif - if (retval == -1) + if (retval == -1) { + #ifdef HAS_VSNPRINTF - retval = vsnprintf(buffer, len, format, ap); + WITH_LC_NUMERIC_SET_TO_NEEDED( + retval = vsnprintf(buffer, len, format, ap); + ); #else - retval = vsprintf(buffer, format, ap); + WITH_LC_NUMERIC_SET_TO_NEEDED( + retval = vsprintf(buffer, format, ap); + ); #endif + + } + va_end(ap); /* vsprintf() shows failure with < 0 */ if (retval < 0 @@ -5271,6 +5285,7 @@ C<sv_vcatpvf> instead, or getting C<vsnprintf>. =cut */ + int Perl_my_vsnprintf(char *buffer, const Size_t len, const char *format, va_list ap) { @@ -5284,6 +5299,7 @@ Perl_my_vsnprintf(char *buffer, const Size_t len, const char *format, va_list ap return 0; #else int retval; + dTHX; # ifdef NEED_VA_COPY va_list apc; @@ -5291,20 +5307,28 @@ Perl_my_vsnprintf(char *buffer, const Size_t len, const char *format, va_list ap PERL_ARGS_ASSERT_MY_VSNPRINTF; Perl_va_copy(ap, apc); # ifdef HAS_VSNPRINTF - retval = vsnprintf(buffer, len, format, apc); -# else + WITH_LC_NUMERIC_SET_TO_NEEDED( + retval = vsnprintf(buffer, len, format, apc); + ); +# else PERL_UNUSED_ARG(len); - retval = vsprintf(buffer, format, apc); + WITH_LC_NUMERIC_SET_TO_NEEDED( + retval = vsprintf(buffer, format, apc); + ); # endif va_end(apc); # else # ifdef HAS_VSNPRINTF - retval = vsnprintf(buffer, len, format, ap); + WITH_LC_NUMERIC_SET_TO_NEEDED( + retval = vsnprintf(buffer, len, format, ap); + ); # else PERL_UNUSED_ARG(len); - retval = vsprintf(buffer, format, ap); + WITH_LC_NUMERIC_SET_TO_NEEDED( + retval = vsprintf(buffer, format, ap); + ); # endif # endif /* #ifdef NEED_VA_COPY */ @@ -5317,6 +5341,7 @@ Perl_my_vsnprintf(char *buffer, const Size_t len, const char *format, va_list ap # endif ) Perl_croak_nocontext("panic: my_vsnprintf buffer overflow"); + return retval; #endif } @@ -6159,8 +6184,13 @@ static void atos_symbolize(atos_context* ctx, return; } } - cnt = snprintf(cmd, sizeof(cmd), ctx->format, - ctx->fname, ctx->object_base_addr, raw_frame); + + dTHX; + WITH_LC_NUMERIC_SET_TO_NEEDED( + cnt = snprintf(cmd, sizeof(cmd), ctx->format, + ctx->fname, ctx->object_base_addr, raw_frame); + ); + if (cnt < sizeof(cmd)) { /* Undo nostdio.h #defines that disable stdio. * This is somewhat naughty, but is used elsewhere |