diff --git a/embed.fnc b/embed.fnc index bbd3198d27be..1d484df4bcea 100644 --- a/embed.fnc +++ b/embed.fnc @@ -3226,8 +3226,7 @@ ST |const char*|my_langinfo|const int item|bool toggle # endif STR |const char *|save_to_buffer|NULLOK const char * string \ |NULLOK const char **buf \ - |NULLOK Size_t *buf_size \ - |const Size_t offset + |NULLOK Size_t *buf_size :# ifndef HAS_POSIX_2008_LOCALE S |const char*|stdize_locale|const int category \ |NULLOK const char* input_locale \ diff --git a/locale.c b/locale.c index 07c38b2c2e07..8f262f204186 100644 --- a/locale.c +++ b/locale.c @@ -1263,7 +1263,7 @@ S_stdize_locale(pTHX_ const int category, retval = input_locale; /* The input can be returned unchanged */ } else { - retval = save_to_buffer(querylocale_c(LC_ALL), buf, buf_size, 0); + retval = save_to_buffer(querylocale_c(LC_ALL), buf, buf_size); } for (i = 0; i < NOMINAL_LC_ALL_INDEX; i++) { @@ -1277,7 +1277,7 @@ S_stdize_locale(pTHX_ const int category, /* Here, there was a problem in an individual category. This means that at * least one adjustment will be necessary. Create a modifiable copy */ - retval = save_to_buffer(input_locale, buf, buf_size, 0); + retval = save_to_buffer(input_locale, buf, buf_size); if (*first_bad != '=') { @@ -2569,7 +2569,7 @@ Perl_setlocale(const int category, const char * locale) /* This toggling back could destroy 'retval' */ retval = save_to_buffer(retval, - &PL_setlocale_buf, &PL_setlocale_bufsize, 0); + &PL_setlocale_buf, &PL_setlocale_bufsize); set_numeric_standard(); } @@ -2582,7 +2582,7 @@ Perl_setlocale(const int category, const char * locale) cat_index = get_category_index(category, NULL); retval = save_to_buffer(setlocale_i(cat_index, locale), - &PL_setlocale_buf, &PL_setlocale_bufsize, 0); + &PL_setlocale_buf, &PL_setlocale_bufsize); if (! retval) { DEBUG_L(PerlIO_printf(Perl_debug_log, "Perl_setlocale returning (null)\n")); @@ -2607,11 +2607,27 @@ Perl_setlocale(const int category, const char * locale) #ifdef USE_LOCALE STATIC const char * -S_save_to_buffer(const char * string, const char **buf, Size_t *buf_size, - const Size_t offset) +S_save_to_buffer(const char * string, const char **buf, Size_t *buf_size) { - /* Copy the NUL-terminated 'string' to 'buf' + 'offset'. 'buf' has size - * 'buf_size', growing it if necessary */ + /* Copy the NUL-terminated 'string' to a buffer whose address before this + * call began at *buf, and whose available length before this call was + * *buf_size. + * + * If the length of 'string' is greater than the space available, the + * buffer is grown accordingly, which may mean that it gets relocated. + * *buf and *buf_size will be updated to reflect this. + * + * Regardless, the function returns a pointer to where 'string' is now + * stored. + * + * 'string' may be NULL, which means no action gets taken, and NULL is + * returned. + * + * If *buf or 'buf_size' are NULL or *buf_size is 0, the buffer is assumed + * empty, and memory is malloc'd. 'buf-size' being NULL is to be used + * when this is a single use buffer, which will shortly be freed by the + * caller. + */ Size_t string_size; @@ -2621,7 +2637,7 @@ S_save_to_buffer(const char * string, const char **buf, Size_t *buf_size, return NULL; } - string_size = strlen(string) + offset + 1; + string_size = strlen(string) + 1; if (buf_size == NULL) { Newx(*buf, string_size, char); @@ -2635,7 +2651,14 @@ S_save_to_buffer(const char * string, const char **buf, Size_t *buf_size, *buf_size = string_size; } - Copy(string, *buf + offset, string_size - offset, char); + { + dTHX_DEBUGGING; + DEBUG_Lv(PerlIO_printf(Perl_debug_log, + "%s: %d: Copying '%s' to %p\n", + __FILE__, __LINE__, string, *buf)); + } + + Copy(string, *buf, string_size, char); return *buf; } @@ -3002,7 +3025,7 @@ S_my_langinfo(const nl_item item, bool toggle) * destroyed by a subsequent setlocale(), such as the * RESTORE_LC_NUMERIC may do just below. */ retval = save_to_buffer(nl_langinfo(item), - &PL_langinfo_buf, &PL_langinfo_bufsize, 0); + &PL_langinfo_buf, &PL_langinfo_bufsize); NL_LANGINFO_UNLOCK; if (toggle) { @@ -3032,7 +3055,7 @@ S_my_langinfo(const nl_item item, bool toggle) /* We have to save it to a buffer, because the freelocale() just below * can invalidate the internal one */ retval = save_to_buffer(nl_langinfo_l(item, cur), - &PL_langinfo_buf, &PL_langinfo_bufsize, 0); + &PL_langinfo_buf, &PL_langinfo_bufsize); } # endif @@ -3119,7 +3142,7 @@ S_my_langinfo(const nl_item item, bool toggle) break; retval = save_to_buffer(Perl_form(aTHX_ "%c%s", precedes, currency), - &PL_langinfo_buf, &PL_langinfo_bufsize, 0); + &PL_langinfo_buf, &PL_langinfo_bufsize); } # ifdef TS_W32_BROKEN_LOCALECONV @@ -3248,8 +3271,7 @@ S_my_langinfo(const nl_item item, bool toggle) } } - retval = save_to_buffer(temp, &PL_langinfo_buf, - &PL_langinfo_bufsize, 0); + retval = save_to_buffer(temp, &PL_langinfo_buf, &PL_langinfo_bufsize); # ifdef TS_W32_BROKEN_LOCALECONV @@ -3383,7 +3405,7 @@ S_my_langinfo(const nl_item item, bool toggle) temp = my_strftime(format, 30, 30, hour, mday, mon, 2011, 0, 0, 0); retval = save_to_buffer(temp, &PL_langinfo_buf, - &PL_langinfo_bufsize, 0); + &PL_langinfo_bufsize); Safefree(temp); /* If the item is 'ALT_DIGITS', 'PL_langinfo_buf' contains the @@ -3460,7 +3482,7 @@ S_my_langinfo(const nl_item item, bool toggle) retval++; retval = save_to_buffer(retval, &PL_langinfo_buf, - &PL_langinfo_bufsize, 0); + &PL_langinfo_bufsize); } break; diff --git a/proto.h b/proto.h index 8e986b34f777..91f503ba73be 100644 --- a/proto.h +++ b/proto.h @@ -5142,7 +5142,7 @@ STATIC void S_new_numeric(pTHX_ const char* newnum); #define PERL_ARGS_ASSERT_NEW_NUMERIC STATIC void S_restore_switched_locale(pTHX_ const int category, const char * const original_locale); #define PERL_ARGS_ASSERT_RESTORE_SWITCHED_LOCALE -STATIC const char * S_save_to_buffer(const char * string, const char **buf, Size_t *buf_size, const Size_t offset) +STATIC const char * S_save_to_buffer(const char * string, const char **buf, Size_t *buf_size) __attribute__warn_unused_result__; #define PERL_ARGS_ASSERT_SAVE_TO_BUFFER