mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
Don't set locale globally, just use it when needed
Previously, we would set the locale on a global level and that could possibly lead to different behaviour in underlying functions. In this commit, we change to code to use the system locale only when calling the libidn2 functions and reset the locale back to "POSIX" when exiting the libidn2 code.
This commit is contained in:
@@ -22,15 +22,12 @@
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif /* ifdef HAVE_LOCALE_H */
|
||||
|
||||
#ifdef HAVE_LIBIDN2
|
||||
#include <idn2.h>
|
||||
#endif /* HAVE_LIBIDN2 */
|
||||
@@ -91,6 +88,9 @@
|
||||
#include <pk11/result.h>
|
||||
#endif /* if USE_PKCS11 */
|
||||
|
||||
#define systemlocale(l) (void)setlocale(l, "")
|
||||
#define resetlocale(l) (void)setlocale(l, "C")
|
||||
|
||||
dig_lookuplist_t lookup_list;
|
||||
dig_serverlist_t server_list;
|
||||
dig_searchlistlist_t search_list;
|
||||
@@ -1295,11 +1295,6 @@ setup_system(bool ipv4only, bool ipv6only) {
|
||||
|
||||
irs_resconf_destroy(&resconf);
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
/* Set locale */
|
||||
(void)setlocale(LC_ALL, "");
|
||||
#endif /* ifdef HAVE_SETLOCALE */
|
||||
|
||||
if (keyfile[0] != 0) {
|
||||
setup_file_key();
|
||||
} else if (keysecret[0] != 0) {
|
||||
@@ -4288,8 +4283,9 @@ destroy_libs(void) {
|
||||
#ifdef HAVE_LIBIDN2
|
||||
static isc_result_t
|
||||
idn_output_filter(isc_buffer_t *buffer, unsigned int used_org) {
|
||||
char src[MXNAME], *dst;
|
||||
char src[MXNAME], *dst = NULL;
|
||||
size_t srclen, dstlen;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
/*
|
||||
* Copy name from 'buffer' to 'src' and terminate it with NULL.
|
||||
@@ -4297,23 +4293,27 @@ idn_output_filter(isc_buffer_t *buffer, unsigned int used_org) {
|
||||
srclen = isc_buffer_usedlength(buffer) - used_org;
|
||||
if (srclen >= sizeof(src)) {
|
||||
warn("Input name too long to perform IDN conversion");
|
||||
return (ISC_R_SUCCESS);
|
||||
goto cleanup;
|
||||
}
|
||||
memmove(src, (char *)isc_buffer_base(buffer) + used_org, srclen);
|
||||
src[srclen] = '\0';
|
||||
|
||||
systemlocale(LC_ALL);
|
||||
|
||||
/*
|
||||
* Convert 'src' to the current locale's character encoding.
|
||||
*/
|
||||
idn_ace_to_locale(src, &dst);
|
||||
|
||||
resetlocale(LC_ALL);
|
||||
|
||||
/*
|
||||
* Check whether the converted name will fit back into 'buffer'.
|
||||
*/
|
||||
dstlen = strlen(dst);
|
||||
if (isc_buffer_length(buffer) < used_org + dstlen) {
|
||||
idn2_free(dst);
|
||||
return (ISC_R_NOSPACE);
|
||||
result = ISC_R_NOSPACE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4326,9 +4326,12 @@ idn_output_filter(isc_buffer_t *buffer, unsigned int used_org) {
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
idn2_free(dst);
|
||||
cleanup:
|
||||
if (dst != NULL) {
|
||||
idn2_free(dst);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*%
|
||||
@@ -4344,6 +4347,8 @@ idn_locale_to_ace(const char *src, char *dst, size_t dstlen) {
|
||||
char *ascii_src;
|
||||
int res;
|
||||
|
||||
systemlocale(LC_ALL);
|
||||
|
||||
/*
|
||||
* We trust libidn2 to return an error if 'src' is too large to be a
|
||||
* valid domain name.
|
||||
@@ -4364,6 +4369,8 @@ idn_locale_to_ace(const char *src, char *dst, size_t dstlen) {
|
||||
(void)strlcpy(dst, final_src, dstlen);
|
||||
|
||||
idn2_free(ascii_src);
|
||||
|
||||
resetlocale(LC_ALL);
|
||||
}
|
||||
|
||||
/*%
|
||||
@@ -4378,6 +4385,8 @@ idn_ace_to_locale(const char *src, char **dst) {
|
||||
char *local_src, *utf8_src;
|
||||
int res;
|
||||
|
||||
systemlocale(LC_ALL);
|
||||
|
||||
/*
|
||||
* We need to:
|
||||
*
|
||||
@@ -4443,6 +4452,8 @@ idn_ace_to_locale(const char *src, char **dst) {
|
||||
idn2_free(utf8_src);
|
||||
|
||||
*dst = local_src;
|
||||
|
||||
resetlocale(LC_ALL);
|
||||
}
|
||||
#endif /* HAVE_LIBIDN2 */
|
||||
|
||||
|
@@ -13,13 +13,10 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif /* ifdef HAVE_LOCALE_H */
|
||||
|
||||
#include <isc/app.h>
|
||||
#include <isc/attributes.h>
|
||||
#include <isc/commandline.h>
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -1423,6 +1424,18 @@ main(int argc, char *argv[]) {
|
||||
xmlInitThreads();
|
||||
#endif /* HAVE_LIBXML2 */
|
||||
|
||||
/*
|
||||
* Technically, this call is superfluous because on startup of the main
|
||||
* program, the portable "C" locale is selected by default. This
|
||||
* explicit call here is for a reference that the BIND 9 code base is
|
||||
* not locale aware and the locale MUST be set to "C" (or "POSIX") when
|
||||
* calling any BIND 9 library code. If you are calling external
|
||||
* libraries that use locale, such calls must be wrapped into
|
||||
* setlocale(LC_ALL, ""); before the call and setlocale(LC_ALL, "C");
|
||||
* after the call, and no BIND 9 library calls must be made in between.
|
||||
*/
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
/*
|
||||
* Record version in core image.
|
||||
* strings named.core | grep "named version:"
|
||||
|
@@ -1363,12 +1363,6 @@ AC_SUBST([CMOCKA_LIBS])
|
||||
|
||||
AM_CONDITIONAL([HAVE_CMOCKA], [test "$with_cmocka" = "yes"])
|
||||
|
||||
#
|
||||
# Check for i18n
|
||||
#
|
||||
AC_CHECK_HEADERS(locale.h)
|
||||
AC_CHECK_FUNCS(setlocale)
|
||||
|
||||
#
|
||||
# was --with-tuning specified?
|
||||
#
|
||||
|
Reference in New Issue
Block a user