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) {