Merge "Fix mbsrtowcs(3)'s handling of len parameter."
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index ecb8b33..438ce03 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -116,11 +116,10 @@
     if (static_cast<uint8_t>((*src)[i]) < 0x80) {
       // Fast path for plain ASCII characters.
       dst[o] = (*src)[i];
-      if ((*src)[i] == '\0') {
-        *src = NULL;
-        return reset_and_return_illegal(EILSEQ, state);
-      }
       r = 1;
+      if ((*src)[i] == '\0') {
+        break;
+      }
     } else {
       r = mbrtowc(dst + o, *src + i, nmc - i, state);
       if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index a5f5f63..f052ce6 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -340,8 +340,19 @@
   ASSERT_EQ(static_cast<wchar_t>(0x00a2), out[1]);
   ASSERT_EQ(static_cast<wchar_t>(0x20ac), out[2]);
   ASSERT_EQ(static_cast<wchar_t>(0x24b62), out[3]);
+  // Check that valid has advanced to the next unread character.
   ASSERT_EQ('e', *valid);
 
+  wmemset(out, L'x', sizeof(out) / sizeof(wchar_t));
+  ASSERT_EQ(2U, mbsrtowcs(out, &valid, 4, ps));
+  ASSERT_EQ(L'e', out[0]);
+  ASSERT_EQ(L'f', out[1]);
+  ASSERT_EQ(L'\0', out[2]);
+  // Check that we didn't clobber the rest of out.
+  ASSERT_EQ(L'x', out[3]);
+  // Check that valid has advanced to the end of the string.
+  ASSERT_EQ(L'\0', *valid);
+
   const char* invalid = "A" "\xc2\x20" "ef";
   ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(out, &invalid, 4, ps));
   EXPECT_EQ(EILSEQ, errno);