diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index b616b984825e..ec1de679c3fe 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -329,6 +329,26 @@ INTERCEPTOR(double, strtod, const char *nptr, char **endptr) { // NOLINT return res; } +INTERCEPTOR(double, strtod_l, const char *nptr, char **endptr, + void *loc) { // NOLINT + ENSURE_MSAN_INITED(); + double res = REAL(strtod_l)(nptr, endptr, loc); // NOLINT + if (!__msan_has_dynamic_component()) { + __msan_unpoison(endptr, sizeof(*endptr)); + } + return res; +} + +INTERCEPTOR(double, __strtod_l, const char *nptr, char **endptr, + void *loc) { // NOLINT + ENSURE_MSAN_INITED(); + double res = REAL(__strtod_l)(nptr, endptr, loc); // NOLINT + if (!__msan_has_dynamic_component()) { + __msan_unpoison(endptr, sizeof(*endptr)); + } + return res; +} + INTERCEPTOR(float, strtof, const char *nptr, char **endptr) { // NOLINT ENSURE_MSAN_INITED(); float res = REAL(strtof)(nptr, endptr); // NOLINT @@ -338,6 +358,26 @@ INTERCEPTOR(float, strtof, const char *nptr, char **endptr) { // NOLINT return res; } +INTERCEPTOR(float, strtof_l, const char *nptr, char **endptr, + void *loc) { // NOLINT + ENSURE_MSAN_INITED(); + float res = REAL(strtof_l)(nptr, endptr, loc); // NOLINT + if (!__msan_has_dynamic_component()) { + __msan_unpoison(endptr, sizeof(*endptr)); + } + return res; +} + +INTERCEPTOR(float, __strtof_l, const char *nptr, char **endptr, + void *loc) { // NOLINT + ENSURE_MSAN_INITED(); + float res = REAL(__strtof_l)(nptr, endptr, loc); // NOLINT + if (!__msan_has_dynamic_component()) { + __msan_unpoison(endptr, sizeof(*endptr)); + } + return res; +} + INTERCEPTOR(long double, strtold, const char *nptr, char **endptr) { // NOLINT ENSURE_MSAN_INITED(); long double res = REAL(strtold)(nptr, endptr); // NOLINT @@ -347,6 +387,26 @@ INTERCEPTOR(long double, strtold, const char *nptr, char **endptr) { // NOLINT return res; } +INTERCEPTOR(long double, strtold_l, const char *nptr, char **endptr, + void *loc) { // NOLINT + ENSURE_MSAN_INITED(); + long double res = REAL(strtold_l)(nptr, endptr, loc); // NOLINT + if (!__msan_has_dynamic_component()) { + __msan_unpoison(endptr, sizeof(*endptr)); + } + return res; +} + +INTERCEPTOR(long double, __strtold_l, const char *nptr, char **endptr, + void *loc) { // NOLINT + ENSURE_MSAN_INITED(); + long double res = REAL(__strtold_l)(nptr, endptr, loc); // NOLINT + if (!__msan_has_dynamic_component()) { + __msan_unpoison(endptr, sizeof(*endptr)); + } + return res; +} + INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) { ENSURE_MSAN_INITED(); int res = REAL(vasprintf)(strp, format, ap); @@ -1320,8 +1380,14 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(strtoul); INTERCEPT_FUNCTION(strtoull); INTERCEPT_FUNCTION(strtod); + INTERCEPT_FUNCTION(strtod_l); + INTERCEPT_FUNCTION(__strtod_l); INTERCEPT_FUNCTION(strtof); + INTERCEPT_FUNCTION(strtof_l); + INTERCEPT_FUNCTION(__strtof_l); INTERCEPT_FUNCTION(strtold); + INTERCEPT_FUNCTION(strtold_l); + INTERCEPT_FUNCTION(__strtold_l); INTERCEPT_FUNCTION(vasprintf); INTERCEPT_FUNCTION(asprintf); INTERCEPT_FUNCTION(vsprintf); diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc index c28f79b4471b..0e89fce953cc 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cc +++ b/compiler-rt/lib/msan/tests/msan_test.cc @@ -1269,6 +1269,17 @@ TEST(MemorySanitizer, strtod) { EXPECT_NOT_POISONED((S8) e); } +#ifdef __GLIBC__ +extern "C" double __strtod_l(const char *nptr, char **endptr, locale_t loc); +TEST(MemorySanitizer, __strtod_l) { + locale_t loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); + char *e; + assert(0 != __strtod_l("1.5", &e, loc)); + EXPECT_NOT_POISONED((S8) e); + freelocale(loc); +} +#endif // __GLIBC__ + TEST(MemorySanitizer, strtof) { char *e; assert(0 != strtof("1.5", &e));