88
99#include " hdr/types/wchar_t.h"
1010#include " src/__support/libc_errno.h"
11+ #include " src/__support/wchar/mbstate.h"
1112#include " src/string/memset.h"
1213#include " src/wchar/mbsrtowcs.h"
1314#include " test/UnitTest/ErrnoCheckingTest.h"
@@ -21,6 +22,7 @@ TEST_F(LlvmLibcMBSRToWCSTest, OneByteOneCharacter) {
2122 const char *ch = " A" ;
2223 wchar_t dest[2 ];
2324 size_t n = LIBC_NAMESPACE::mbsrtowcs (dest, &ch, 2 , mb);
25+ ASSERT_ERRNO_SUCCESS ();
2426 ASSERT_TRUE (dest[0 ] == L' A' );
2527 ASSERT_TRUE (dest[1 ] == L' \0 ' );
2628 // Should not count null terminator in number
@@ -33,6 +35,7 @@ TEST_F(LlvmLibcMBSRToWCSTest, MultiByteOneCharacter) {
3335 const char *src = " \xf0\x9f\x98\xb9 " ; // laughing cat emoji 😹
3436 wchar_t dest[2 ];
3537 size_t n = LIBC_NAMESPACE::mbsrtowcs (dest, &src, 2 , nullptr );
38+ ASSERT_ERRNO_SUCCESS ();
3639 ASSERT_EQ (static_cast <int >(dest[0 ]), 128569 );
3740 ASSERT_TRUE (dest[1 ] == L' \0 ' );
3841 // Should not count null terminator in number
@@ -46,6 +49,7 @@ TEST_F(LlvmLibcMBSRToWCSTest, MultiByteTwoCharacters) {
4649 const char *src = " \xf0\x9f\x98\xb9\xf0\x9f\x98\xb9 " ;
4750 wchar_t dest[3 ];
4851 size_t n = LIBC_NAMESPACE::mbsrtowcs (dest, &src, 3 , nullptr );
52+ ASSERT_ERRNO_SUCCESS ();
4953 ASSERT_EQ (static_cast <int >(dest[0 ]), 128569 );
5054 ASSERT_EQ (static_cast <int >(dest[1 ]), 128569 );
5155 ASSERT_TRUE (dest[2 ] == L' \0 ' );
@@ -62,6 +66,7 @@ TEST_F(LlvmLibcMBSRToWCSTest, ReadLessThanStringLength) {
6266 const char *check = src;
6367 wchar_t dest[3 ];
6468 size_t n = LIBC_NAMESPACE::mbsrtowcs (dest, &src, 3 , nullptr );
69+ ASSERT_ERRNO_SUCCESS ();
6570 // Should have read 3 emojis
6671 ASSERT_EQ (static_cast <int >(n), 3 );
6772 ASSERT_EQ (static_cast <int >(dest[0 ]), 128569 );
@@ -98,10 +103,26 @@ TEST_F(LlvmLibcMBSRToWCSTest, NullDestination) {
98103 const char *src =
99104 " \xf0\x9f\x98\xb9\xf0\x9f\x98\xb9\xf0\x9f\x98\xb9\xf0\x9f\x98\xb9 " ;
100105 size_t n = LIBC_NAMESPACE::mbsrtowcs (nullptr , &src, 5 , nullptr );
106+ ASSERT_ERRNO_SUCCESS ();
101107 // Null destination should still return correct number of read chars
102108 ASSERT_EQ (static_cast <int >(n), 4 );
103109}
104110
111+ TEST_F (LlvmLibcMBSRToWCSTest, InvalidMBState) {
112+ mbstate_t *mb;
113+ LIBC_NAMESPACE::internal::mbstate inv;
114+ inv.total_bytes = 6 ;
115+ mb = reinterpret_cast <mbstate_t *>(&inv);
116+ // Four laughing cat emojis "😹😹😹😹"
117+ const char *src =
118+ " \xf0\x9f\x98\xb9\xf0\x9f\x98\xb9\xf0\x9f\x98\xb9\xf0\x9f\x98\xb9 " ;
119+ wchar_t dest[3 ];
120+ size_t n = LIBC_NAMESPACE::mbsrtowcs (dest, &src, 3 , mb);
121+ // Should fail from invalid mbstate
122+ ASSERT_EQ (static_cast <int >(n), -1 );
123+ ASSERT_ERRNO_EQ (EINVAL);
124+ }
125+
105126#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
106127TEST_F (LlvmLibcMBSRToWCSTest, NullSource) {
107128 // Passing in a nullptr source should crash the program
0 commit comments