Index: compiler-rt/trunk/lib/asan/tests/asan_test.cc =================================================================== --- compiler-rt/trunk/lib/asan/tests/asan_test.cc +++ compiler-rt/trunk/lib/asan/tests/asan_test.cc @@ -1284,3 +1284,33 @@ ASSERT_EQ(0, res); } #endif + +#if SANITIZER_TEST_HAS_PRINTF_L +static int vsnprintf_l_wrapper(char *s, size_t n, + locale_t l, const char *format, ...) { + va_list va; + va_start(va, format); + int res = vsnprintf_l(s, n , l, format, va); + va_end(va); + return res; +} + +TEST(AddressSanitizer, snprintf_l) { + char buff[5]; + // Check that snprintf_l() works fine with Asan. + int res = snprintf_l(buff, 5, + _LIBCPP_GET_C_LOCALE, "%s", "snprintf_l()"); + EXPECT_EQ(12, res); + // Check that vsnprintf_l() works fine with Asan. + res = vsnprintf_l_wrapper(buff, 5, + _LIBCPP_GET_C_LOCALE, "%s", "vsnprintf_l()"); + EXPECT_EQ(13, res); + + EXPECT_DEATH(snprintf_l(buff, 10, + _LIBCPP_GET_C_LOCALE, "%s", "snprintf_l()"), + "AddressSanitizer: stack-buffer-overflow"); + EXPECT_DEATH(vsnprintf_l_wrapper(buff, 10, + _LIBCPP_GET_C_LOCALE, "%s", "vsnprintf_l()"), + "AddressSanitizer: stack-buffer-overflow"); +} +#endif Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -915,6 +915,16 @@ va_list ap) VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) +#if SANITIZER_INTERCEPT_PRINTF_L +INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc, + const char *format, va_list ap) +VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap) + +INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc, + const char *format, ...) +FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format) +#endif // SANITIZER_INTERCEPT_PRINTF_L + INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) @@ -991,6 +1001,14 @@ #define INIT_PRINTF #endif +#if SANITIZER_INTERCEPT_PRINTF_L +#define INIT_PRINTF_L \ + COMMON_INTERCEPT_FUNCTION(snprintf_l); \ + COMMON_INTERCEPT_FUNCTION(vsnprintf_l); +#else +#define INIT_PRINTF_L +#endif + #if SANITIZER_INTERCEPT_ISOC99_PRINTF #define INIT_ISOC99_PRINTF \ COMMON_INTERCEPT_FUNCTION(__isoc99_printf); \ @@ -4768,6 +4786,7 @@ INIT_SCANF; INIT_ISOC99_SCANF; INIT_PRINTF; + INIT_PRINTF_L; INIT_ISOC99_PRINTF; INIT_FREXP; INIT_FREXPF_FREXPL; Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -85,6 +85,7 @@ #ifndef SANITIZER_INTERCEPT_PRINTF # define SANITIZER_INTERCEPT_PRINTF SI_NOT_WINDOWS +# define SANITIZER_INTERCEPT_PRINTF_L SI_FREEBSD # define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_LINUX_NOT_ANDROID #endif Index: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_test_utils.h =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_test_utils.h +++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_test_utils.h @@ -118,4 +118,10 @@ # define SANITIZER_TEST_HAS_STRNLEN 0 #endif +#if defined(__FreeBSD__) +# define SANITIZER_TEST_HAS_PRINTF_L 1 +#else +# define SANITIZER_TEST_HAS_PRINTF_L 0 +#endif + #endif // SANITIZER_TEST_UTILS_H