Fix mbsnrtowcs where `dst` is null.

POSIX is its usual unintelligible self
(http://pubs.opengroup.org/onlinepubs/9699919799/functions/mbsrtowcs.html),
but the ISO C11 standard (7.29.6.4.1 paragraph 2) is pretty clear: *src
should change if and only if dst is non-null.

Bug: https://code.google.com/p/android/issues/detail?id=166381
Test: bionic tests
Change-Id: Ibc631cfa5b1bf4a6f56963feba9f0eea27b07984
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index db51c08..34ed5a7 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -303,7 +303,7 @@
   ASSERT_EQ(EILSEQ, errno);
 }
 
-void test_mbrtowc_incomplete(mbstate_t* ps) {
+static void test_mbrtowc_incomplete(mbstate_t* ps) {
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
@@ -340,10 +340,13 @@
   test_mbrtowc_incomplete(NULL);
 }
 
-void test_mbsrtowcs(mbstate_t* ps) {
+static void test_mbsrtowcs(mbstate_t* ps) {
+  constexpr const char* VALID = "A" "\xc2\xa2" "\xe2\x82\xac" "\xf0\xa4\xad\xa2" "ef";
+  constexpr const char* INVALID = "A" "\xc2\x20" "ef";
+  constexpr const char* INCOMPLETE = "A" "\xc2";
   wchar_t out[4];
 
-  const char* valid = "A" "\xc2\xa2" "\xe2\x82\xac" "\xf0\xa4\xad\xa2" "ef";
+  const char* valid = VALID;
   ASSERT_EQ(4U, mbsrtowcs(out, &valid, 4, ps));
   ASSERT_EQ(L'A', out[0]);
   ASSERT_EQ(static_cast<wchar_t>(0x00a2), out[1]);
@@ -362,15 +365,27 @@
   // Check that valid has advanced to the end of the string.
   ASSERT_EQ(nullptr, valid);
 
-  const char* invalid = "A" "\xc2\x20" "ef";
+  const char* invalid = INVALID;
   ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(out, &invalid, 4, ps));
   EXPECT_EQ(EILSEQ, errno);
   ASSERT_EQ('\xc2', *invalid);
 
-  const char* incomplete = "A" "\xc2";
+  const char* incomplete = INCOMPLETE;
   ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(out, &incomplete, 2, ps));
   EXPECT_EQ(EILSEQ, errno);
   ASSERT_EQ('\xc2', *incomplete);
+
+  // If dst is null, *src shouldn't be updated.
+  // https://code.google.com/p/android/issues/detail?id=166381
+  const char* mbs = VALID;
+  EXPECT_EQ(6U, mbsrtowcs(nullptr, &mbs, 0, ps));
+  EXPECT_EQ(VALID, mbs);
+  mbs = INVALID;
+  EXPECT_EQ(static_cast<size_t>(-1), mbsrtowcs(nullptr, &mbs, 0, ps));
+  EXPECT_EQ(INVALID, mbs);
+  mbs = INCOMPLETE;
+  EXPECT_EQ(static_cast<size_t>(-1), mbsrtowcs(nullptr, &mbs, 0, ps));
+  EXPECT_EQ(INCOMPLETE, mbs);
 }
 
 TEST(wchar, mbsrtowcs) {