Index: lib/msan/msan_interceptors.cc =================================================================== --- lib/msan/msan_interceptors.cc +++ lib/msan/msan_interceptors.cc @@ -294,132 +294,54 @@ return res; } -INTERCEPTOR(long, strtol, const char *nptr, char **endptr, // NOLINT - int base) { - ENSURE_MSAN_INITED(); - long res = REAL(strtol)(nptr, endptr, base); // NOLINT - if (!__msan_has_dynamic_component()) { - __msan_unpoison(endptr, sizeof(*endptr)); +// Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to +// deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO. +#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \ + ENSURE_MSAN_INITED(); \ + ret_type res = REAL(func)(__VA_ARGS__); \ + if (!__msan_has_dynamic_component()) { \ + __msan_unpoison(endptr, sizeof(*endptr)); \ + } \ + return res; + +#define INTERCEPTOR_STRTO(ret_type, func) \ + INTERCEPTOR(ret_type, func, const char *nptr, char **endptr) { \ + INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr); \ } - return res; -} -INTERCEPTOR(long long, strtoll, const char *nptr, char **endptr, // NOLINT - int base) { - ENSURE_MSAN_INITED(); - long res = REAL(strtoll)(nptr, endptr, base); //NOLINT - if (!__msan_has_dynamic_component()) { - __msan_unpoison(endptr, sizeof(*endptr)); +#define INTERCEPTOR_STRTO_BASE(ret_type, func) \ + INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, int base) { \ + INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base); \ } - return res; -} -INTERCEPTOR(unsigned long, strtoul, const char *nptr, char **endptr, // NOLINT - int base) { - ENSURE_MSAN_INITED(); - unsigned long res = REAL(strtoul)(nptr, endptr, base); // NOLINT - if (!__msan_has_dynamic_component()) { - __msan_unpoison(endptr, sizeof(*endptr)); +#define INTERCEPTOR_STRTO_LOC(ret_type, func) \ + INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, void *loc) { \ + INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc); \ } - return res; -} -INTERCEPTOR(unsigned long long, strtoull, const char *nptr, // NOLINT - char **endptr, int base) { - ENSURE_MSAN_INITED(); - unsigned long res = REAL(strtoull)(nptr, endptr, base); // NOLINT - if (!__msan_has_dynamic_component()) { - __msan_unpoison(endptr, sizeof(*endptr)); +#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func) \ + INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, int base, \ + void *loc) { \ + INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc); \ } - return res; -} -INTERCEPTOR(double, strtod, const char *nptr, char **endptr) { // NOLINT - ENSURE_MSAN_INITED(); - double res = REAL(strtod)(nptr, endptr); // 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(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 - 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(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 - 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(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_STRTO(double, strtod) // NOLINT +INTERCEPTOR_STRTO(float, strtof) // NOLINT +INTERCEPTOR_STRTO(long double, strtold) // NOLINT +INTERCEPTOR_STRTO_BASE(long, strtol) // NOLINT +INTERCEPTOR_STRTO_BASE(long long, strtoll) // NOLINT +INTERCEPTOR_STRTO_BASE(unsigned long, strtoul) // NOLINT +INTERCEPTOR_STRTO_BASE(unsigned long long, strtoull) // NOLINT +INTERCEPTOR_STRTO_LOC(double, strtod_l) // NOLINT +INTERCEPTOR_STRTO_LOC(double, __strtod_l) // NOLINT +INTERCEPTOR_STRTO_LOC(float, strtof_l) // NOLINT +INTERCEPTOR_STRTO_LOC(float, __strtof_l) // NOLINT +INTERCEPTOR_STRTO_LOC(long double, strtold_l) // NOLINT +INTERCEPTOR_STRTO_LOC(long double, __strtold_l) // NOLINT +INTERCEPTOR_STRTO_BASE_LOC(long, strtol_l) // NOLINT +INTERCEPTOR_STRTO_BASE_LOC(long long, strtoll_l) // NOLINT +INTERCEPTOR_STRTO_BASE_LOC(unsigned long, strtoul_l) // NOLINT +INTERCEPTOR_STRTO_BASE_LOC(unsigned long long, strtoull_l) // NOLINT INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) { ENSURE_MSAN_INITED(); @@ -1498,6 +1420,10 @@ INTERCEPT_FUNCTION(strtold); INTERCEPT_FUNCTION(strtold_l); INTERCEPT_FUNCTION(__strtold_l); + INTERCEPT_FUNCTION(strtol_l); + INTERCEPT_FUNCTION(strtoll_l); + INTERCEPT_FUNCTION(strtoul_l); + INTERCEPT_FUNCTION(strtoull_l); INTERCEPT_FUNCTION(vasprintf); INTERCEPT_FUNCTION(asprintf); INTERCEPT_FUNCTION(vsprintf); Index: lib/msan/tests/msan_test.cc =================================================================== --- lib/msan/tests/msan_test.cc +++ lib/msan/tests/msan_test.cc @@ -1528,29 +1528,55 @@ EXPECT_POISONED(a[7]); } -TEST(MemorySanitizer, strtol) { - char *e; - ASSERT_EQ(1, strtol("1", &e, 10)); - EXPECT_NOT_POISONED((S8) e); -} +#define TEST_STRTO_INT(func_name) \ + TEST(MemorySanitizer, func_name) { \ + char *e; \ + EXPECT_EQ(1, func_name("1", &e, 10)); \ + EXPECT_NOT_POISONED((S8)e); \ + } -TEST(MemorySanitizer, strtoll) { - char *e; - ASSERT_EQ(1, strtoll("1", &e, 10)); - EXPECT_NOT_POISONED((S8) e); -} +#define TEST_STRTO_FLOAT(func_name) \ + TEST(MemorySanitizer, func_name) { \ + char *e; \ + EXPECT_NE(0, func_name("1.5", &e)); \ + EXPECT_NOT_POISONED((S8)e); \ + } -TEST(MemorySanitizer, strtoul) { - char *e; - ASSERT_EQ(1, strtoul("1", &e, 10)); - EXPECT_NOT_POISONED((S8) e); -} +#define TEST_STRTO_FLOAT_LOC(func_name) \ + TEST(MemorySanitizer, func_name) { \ + locale_t loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); \ + char *e; \ + EXPECT_NE(0, func_name("1.5", &e, loc)); \ + EXPECT_NOT_POISONED((S8)e); \ + freelocale(loc); \ + } -TEST(MemorySanitizer, strtoull) { - char *e; - ASSERT_EQ(1, strtoull("1", &e, 10)); - EXPECT_NOT_POISONED((S8) e); -} +#define TEST_STRTO_INT_LOC(func_name) \ + TEST(MemorySanitizer, func_name) { \ + locale_t loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); \ + char *e; \ + ASSERT_EQ(1, func_name("1", &e, 10, loc)); \ + EXPECT_NOT_POISONED((S8)e); \ + freelocale(loc); \ + } + +TEST_STRTO_INT(strtol) +TEST_STRTO_INT(strtoll) +TEST_STRTO_INT(strtoul) +TEST_STRTO_INT(strtoull) + +TEST_STRTO_FLOAT(strtof) +TEST_STRTO_FLOAT(strtod) +TEST_STRTO_FLOAT(strtold) + +TEST_STRTO_FLOAT_LOC(strtof_l) +TEST_STRTO_FLOAT_LOC(strtod_l) +TEST_STRTO_FLOAT_LOC(strtold_l) + +TEST_STRTO_INT_LOC(strtol_l) +TEST_STRTO_INT_LOC(strtoll_l) +TEST_STRTO_INT_LOC(strtoul_l) +TEST_STRTO_INT_LOC(strtoull_l) // https://code.google.com/p/memory-sanitizer/issues/detail?id=36 TEST(MemorySanitizer, DISABLED_strtoimax) { @@ -1566,35 +1592,16 @@ EXPECT_NOT_POISONED((S8) e); } -TEST(MemorySanitizer, strtod) { - char *e; - ASSERT_NE(0, strtod("1.5", &e)); - EXPECT_NOT_POISONED((S8) e); -} - #ifdef __GLIBC__ +extern "C" float __strtof_l(const char *nptr, char **endptr, locale_t loc); +TEST_STRTO_FLOAT_LOC(__strtof_l) 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_NE(0, __strtod_l("1.5", &e, loc)); - EXPECT_NOT_POISONED((S8) e); - freelocale(loc); -} +TEST_STRTO_FLOAT_LOC(__strtod_l) +extern "C" long double __strtold_l(const char *nptr, char **endptr, + locale_t loc); +TEST_STRTO_FLOAT_LOC(__strtold_l) #endif // __GLIBC__ -TEST(MemorySanitizer, strtof) { - char *e; - ASSERT_NE(0, strtof("1.5", &e)); - EXPECT_NOT_POISONED((S8) e); -} - -TEST(MemorySanitizer, strtold) { - char *e; - ASSERT_NE(0, strtold("1.5", &e)); - EXPECT_NOT_POISONED((S8) e); -} - TEST(MemorySanitizer, modf) { double x, y; x = modf(2.1, &y);