Fix mbrtoc32 test for musl and glibc. glibc and musl both interpreted the spec differently than we did (better, imo) for the return value of a zero-length conversion. Fix the test to handle that. Also converted the test from ASSERT to EXPECT to reduce the number of builds needed to find failures. Bug: None Test: ./tests/run-on-host.sh glibc --gtest_filter="uchar.*" Change-Id: Id74364040ce3b0e21bacd78f70467053cc8a6058
diff --git a/tests/uchar_test.cpp b/tests/uchar_test.cpp index 1936a8d..e321d83 100644 --- a/tests/uchar_test.cpp +++ b/tests/uchar_test.cpp
@@ -304,46 +304,86 @@ TEST(uchar, mbrtoc32) { char32_t out[8]; + // C23 says: + // + // Returns: + // + // 0 if the next n or fewer bytes complete the multibyte character that + // corresponds to the null wide character (which is the value stored). + // + // (size_t)(-2) if the next n bytes contribute to an incomplete (but + // potentially valid) multibyte character, and all n bytes have been + // processed (no value is stored). + // + // Bionic historically interpreted the behavior when n is 0 to be the next 0 + // bytes decoding to the null. That's a pretty bad interpretation, and both + // glibc and musl return -2 for that case. + // + // The test currently checks the incorrect behavior for bionic because gtest + // doesn't support explicit xfail annotations. The behavior difference here + // should be fixed, but danalbert wants to add more tests before tackling the + // bugs. +#ifdef __ANDROID__ + const size_t expected_result_for_zero_length = 0U; +#else + const size_t expected_result_for_zero_length = static_cast<size_t>(-2); +#endif + out[0] = L'x'; - ASSERT_EQ(0U, mbrtoc32(out, "hello", 0, nullptr)); - ASSERT_EQ(static_cast<char32_t>(L'x'), out[0]); + EXPECT_EQ(expected_result_for_zero_length, mbrtoc32(out, "hello", 0, nullptr)); + EXPECT_EQ(static_cast<char32_t>(L'x'), out[0]); - ASSERT_EQ(0U, mbrtoc32(out, "hello", 0, nullptr)); - ASSERT_EQ(0U, mbrtoc32(out, "", 0, nullptr)); - ASSERT_EQ(1U, mbrtoc32(out, "hello", 1, nullptr)); - ASSERT_EQ(static_cast<char32_t>(L'h'), out[0]); + EXPECT_EQ(expected_result_for_zero_length, mbrtoc32(out, "hello", 0, nullptr)); + EXPECT_EQ(expected_result_for_zero_length, mbrtoc32(out, "", 0, nullptr)); + EXPECT_EQ(1U, mbrtoc32(out, "hello", 1, nullptr)); + EXPECT_EQ(static_cast<char32_t>(L'h'), out[0]); - ASSERT_EQ(0U, mbrtoc32(nullptr, "hello", 0, nullptr)); - ASSERT_EQ(0U, mbrtoc32(nullptr, "", 0, nullptr)); - ASSERT_EQ(1U, mbrtoc32(nullptr, "hello", 1, nullptr)); + EXPECT_EQ(expected_result_for_zero_length, mbrtoc32(nullptr, "hello", 0, nullptr)); + EXPECT_EQ(expected_result_for_zero_length, mbrtoc32(nullptr, "", 0, nullptr)); + EXPECT_EQ(1U, mbrtoc32(nullptr, "hello", 1, nullptr)); - ASSERT_EQ(0U, mbrtoc32(nullptr, nullptr, 0, nullptr)); + EXPECT_EQ(0U, mbrtoc32(nullptr, nullptr, 0, nullptr)); ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); uselocale(LC_GLOBAL_LOCALE); // 1-byte UTF-8. - ASSERT_EQ(1U, mbrtoc32(out, "abcdef", 6, nullptr)); - ASSERT_EQ(static_cast<char32_t>(L'a'), out[0]); + EXPECT_EQ(1U, mbrtoc32(out, "abcdef", 6, nullptr)); + EXPECT_EQ(static_cast<char32_t>(L'a'), out[0]); // 2-byte UTF-8. - ASSERT_EQ(2U, mbrtoc32(out, "\xc2\xa2" "cdef", 6, nullptr)); - ASSERT_EQ(static_cast<char32_t>(0x00a2), out[0]); + EXPECT_EQ(2U, mbrtoc32(out, + "\xc2\xa2" + "cdef", + 6, nullptr)); + EXPECT_EQ(static_cast<char32_t>(0x00a2), out[0]); // 3-byte UTF-8. - ASSERT_EQ(3U, mbrtoc32(out, "\xe2\x82\xac" "def", 6, nullptr)); - ASSERT_EQ(static_cast<char32_t>(0x20ac), out[0]); + EXPECT_EQ(3U, mbrtoc32(out, + "\xe2\x82\xac" + "def", + 6, nullptr)); + EXPECT_EQ(static_cast<char32_t>(0x20ac), out[0]); // 4-byte UTF-8. - ASSERT_EQ(4U, mbrtoc32(out, "\xf0\xa4\xad\xa2" "ef", 6, nullptr)); - ASSERT_EQ(static_cast<char32_t>(0x24b62), out[0]); + EXPECT_EQ(4U, mbrtoc32(out, + "\xf0\xa4\xad\xa2" + "ef", + 6, nullptr)); + EXPECT_EQ(static_cast<char32_t>(0x24b62), out[0]); #if defined(__BIONIC__) // glibc allows this. // Illegal 5-byte UTF-8. errno = 0; - ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(out, "\xf8\xa1\xa2\xa3\xa4" "f", 6, nullptr)); - ASSERT_EQ(EILSEQ, errno); + EXPECT_EQ(static_cast<size_t>(-1), mbrtoc32(out, + "\xf8\xa1\xa2\xa3\xa4" + "f", + 6, nullptr)); + EXPECT_EQ(EILSEQ, errno); #endif // Illegal over-long sequence. errno = 0; - ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(out, "\xf0\x82\x82\xac" "ef", 6, nullptr)); - ASSERT_EQ(EILSEQ, errno); + EXPECT_EQ(static_cast<size_t>(-1), mbrtoc32(out, + "\xf0\x82\x82\xac" + "ef", + 6, nullptr)); + EXPECT_EQ(EILSEQ, errno); } void test_mbrtoc32_incomplete(mbstate_t* ps) {