#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 */
#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;
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) {
#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.
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;
}
/*
/*
* Clean up.
*/
- idn2_free(dst);
+cleanup:
+ if (dst != NULL) {
+ idn2_free(dst);
+ }
- return (ISC_R_SUCCESS);
+ return (result);
}
/*%
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.
(void)strlcpy(dst, final_src, dstlen);
idn2_free(ascii_src);
+
+ resetlocale(LC_ALL);
}
/*%
char *local_src, *utf8_src;
int res;
+ systemlocale(LC_ALL);
+
/*
* We need to:
*
idn2_free(utf8_src);
*dst = local_src;
+
+ resetlocale(LC_ALL);
}
#endif /* HAVE_LIBIDN2 */
#include <ctype.h>
#include <inttypes.h>
+#include <locale.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
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:"