[Sanitizer] Revert some parts of r186109 related to mbstowcs-and-friends interceptors

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@186155 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index b49df52..fe75d35 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -1210,6 +1210,19 @@
   free(pbuf);
 }
 
+TEST(MemorySanitizer, mbstowcs) {
+  const char *x = "abc";
+  wchar_t buff[10];
+  int res = mbstowcs(buff, x, 2);
+  EXPECT_EQ(2, res);
+  EXPECT_EQ(L'a', buff[0]);
+  EXPECT_EQ(L'b', buff[1]);
+  EXPECT_POISONED(buff[2]);
+  res = mbstowcs(buff, x, 10);
+  EXPECT_EQ(3, res);
+  EXPECT_NOT_POISONED(buff[3]);
+}
+
 TEST(MemorySanitizer, wcstombs) {
   const wchar_t *x = L"abc";
   char buff[10];
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 329ff2c..d9c6fc2 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1540,8 +1540,10 @@
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
   SIZE_T res = REAL(mbstowcs)(dest, src, len);
-  if (res != (SIZE_T) - 1 && dest)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+  if (res != (SIZE_T)-1 && dest) {
+    SIZE_T write_cnt = res + (res < len);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+  }
   return res;
 }
 
@@ -1549,12 +1551,13 @@
             void *ps) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
-  if (src) {
-    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
-  }
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
-  if (res != (SIZE_T) - 1 && dest)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+  if (res != (SIZE_T)-1 && dest) {
+    // Terminating '\0' is not printed iff *src is cleared.
+    SIZE_T write_cnt = res + !(*src);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+  }
   return res;
 }
 
@@ -1570,13 +1573,16 @@
             SIZE_T len, void *ps) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
-  if (src) {
+  if (nms) {
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
-    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
   }
   SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
-  if (res != (SIZE_T) - 1 && dest)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+  if (res != (SIZE_T)-1 && dest && nms) {
+    // Terminating '\0' is not printed iff *src is cleared.
+    SIZE_T write_cnt = res + !(*src);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+  }
   return res;
 }
 
@@ -1590,8 +1596,10 @@
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
   SIZE_T res = REAL(wcstombs)(dest, src, len);
-  if (res != (SIZE_T) - 1 && dest)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+  if (res != (SIZE_T)-1 && dest) {
+    SIZE_T write_cnt = res + (res < len);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+  }
   return res;
 }
 
@@ -1599,12 +1607,13 @@
             void *ps) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
-  if (src) {
-    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
-  }
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
-  if (res != (SIZE_T) - 1 && dest)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+  if (res != (SIZE_T)-1 && dest) {
+    // Terminating '\0' is not printed iff *src is cleared.
+    SIZE_T write_cnt = res + !(*src);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+  }
   return res;
 }
 
@@ -1620,13 +1629,16 @@
             SIZE_T len, void *ps) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
-  if (src) {
+  if (nms) {
     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
-    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
   }
   SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
-  if (res != (SIZE_T) - 1 && dest)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+  if (res != (SIZE_T)-1 && dest && nms) {
+    // Terminating '\0' is not printed iff *src is cleared.
+    SIZE_T write_cnt = res + !(*src);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+  }
   return res;
 }