summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/msan/tests/msan_test.cc10
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc23
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h3
-rw-r--r--compiler-rt/test/sanitizer_common/TestCases/wctomb.c14
4 files changed, 50 insertions, 0 deletions
diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc
index d2002d19230..9d2f5a73be3 100644
--- a/compiler-rt/lib/msan/tests/msan_test.cc
+++ b/compiler-rt/lib/msan/tests/msan_test.cc
@@ -2123,6 +2123,16 @@ TEST(MemorySanitizer, wcrtomb) {
EXPECT_EQ(buff[0], 'a');
}
+TEST(MemorySanitizer, wctomb) {
+ wchar_t x = L'a';
+ char buff[10];
+ wctomb(nullptr, x);
+ int res = wctomb(buff, x);
+ EXPECT_EQ(res, 1);
+ EXPECT_EQ(buff[0], 'a');
+ EXPECT_POISONED(buff[1]);
+}
+
TEST(MemorySanitizer, wmemset) {
wchar_t x[25];
break_optimization(x);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 4ea274f7840..b3be48d7521 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -3540,6 +3540,28 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
#define INIT_WCRTOMB
#endif
+#if SANITIZER_INTERCEPT_WCTOMB
+INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src);
+ if (!dest)
+ return REAL(wctomb)(dest, src);
+
+ char local_dest[32];
+ int res = REAL(wctomb)(local_dest, src);
+ if (res != -1) {
+ CHECK_LE(res, sizeof(local_dest));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
+ REAL(memcpy)(dest, local_dest, res);
+ }
+ return res;
+}
+
+#define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb);
+#else
+#define INIT_WCTOMB
+#endif
+
#if SANITIZER_INTERCEPT_TCGETATTR
INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
void *ctx;
@@ -9616,6 +9638,7 @@ static void InitializeCommonInterceptors() {
INIT_WCSTOMBS;
INIT_WCSNRTOMBS;
INIT_WCRTOMB;
+ INIT_WCTOMB;
INIT_TCGETATTR;
INIT_REALPATH;
INIT_CANONICALIZE_FILE_NAME;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index a4116f8a0aa..3cbdd0101a0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -283,6 +283,9 @@
#define SANITIZER_INTERCEPT_WCRTOMB \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
SI_SOLARIS)
+#define SANITIZER_INTERCEPT_WCTOMB \
+ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
+ SI_SOLARIS)
#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS
#define SANITIZER_INTERCEPT_REALPATH SI_POSIX
#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME \
diff --git a/compiler-rt/test/sanitizer_common/TestCases/wctomb.c b/compiler-rt/test/sanitizer_common/TestCases/wctomb.c
new file mode 100644
index 00000000000..87089d2ce48
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/wctomb.c
@@ -0,0 +1,14 @@
+// RUN: %clang %s -o %t && %run %t 2>&1
+
+#include <assert.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+ char buff[10];
+ wchar_t x = L'a';
+ wctomb(NULL, x);
+ int res = wctomb(buff, x);
+ assert(res == 1);
+ assert(buff[0] == 'a');
+ return 0;
+}
OpenPOWER on IntegriCloud