@@ -83,6 +83,50 @@ TEST(LlvmLibcWcsnrtombs, DestLimit) {
8383 ASSERT_EQ (mbs[4 ], ' \x01 ' );
8484}
8585
86+ TEST (LlvmLibcWcsnrtombs, SrcLimit) {
87+ LIBC_NAMESPACE::internal::mbstate state;
88+
89+ // / clown emoji, sigma symbol, y with diaeresis, letter A
90+ const wchar_t src[] = {static_cast <wchar_t >(0x1f921 ),
91+ static_cast <wchar_t >(0x2211 ),
92+ static_cast <wchar_t >(0xff ), static_cast <wchar_t >(0x41 ),
93+ static_cast <wchar_t >(0x0 )};
94+ const wchar_t *cur = src;
95+
96+ char mbs[11 ];
97+ for (int i = 0 ; i < 11 ; ++i)
98+ mbs[i] = ' \x01 ' ; // dummy initial values
99+
100+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs (mbs, &cur, 2 , 11 , &state);
101+ ASSERT_TRUE (res.has_value ());
102+ ASSERT_EQ (res.value (), static_cast <size_t >(7 ));
103+ ASSERT_EQ (cur, src + 2 );
104+ ASSERT_EQ (mbs[0 ], ' \xF0 ' ); // clown begin
105+ ASSERT_EQ (mbs[1 ], ' \x9F ' );
106+ ASSERT_EQ (mbs[2 ], ' \xA4 ' );
107+ ASSERT_EQ (mbs[3 ], ' \xA1 ' );
108+ ASSERT_EQ (mbs[4 ], ' \xE2 ' ); // sigma begin
109+ ASSERT_EQ (mbs[5 ], ' \x88 ' );
110+ ASSERT_EQ (mbs[6 ], ' \x91 ' );
111+ ASSERT_EQ (mbs[7 ], ' \x01 ' );
112+
113+ res = LIBC_NAMESPACE::internal::wcsnrtombs (mbs + res.value (), &cur, 100 , 11 , &state);
114+ ASSERT_TRUE (res.has_value ());
115+ ASSERT_EQ (res.value (), static_cast <size_t >(3 ));
116+ ASSERT_EQ (cur, nullptr );
117+ ASSERT_EQ (mbs[0 ], ' \xF0 ' ); // clown begin
118+ ASSERT_EQ (mbs[1 ], ' \x9F ' );
119+ ASSERT_EQ (mbs[2 ], ' \xA4 ' );
120+ ASSERT_EQ (mbs[3 ], ' \xA1 ' );
121+ ASSERT_EQ (mbs[4 ], ' \xE2 ' ); // sigma begin
122+ ASSERT_EQ (mbs[5 ], ' \x88 ' );
123+ ASSERT_EQ (mbs[6 ], ' \x91 ' );
124+ ASSERT_EQ (mbs[7 ], ' \xC3 ' ); // y diaeresis begin
125+ ASSERT_EQ (mbs[8 ], ' \xBF ' );
126+ ASSERT_EQ (mbs[9 ], ' \x41 ' ); // A begin
127+ ASSERT_EQ (mbs[10 ], ' \0 ' ); // null terminator
128+ }
129+
86130TEST (LlvmLibcWcsnrtombs, NullDest) {
87131 LIBC_NAMESPACE::internal::mbstate state1;
88132
@@ -106,23 +150,40 @@ TEST(LlvmLibcWcsnrtombs, NullDest) {
106150 ASSERT_EQ (cur, nullptr );
107151}
108152
109- TEST (LlvmLibcWcsnrtombs, ErrorTest) {
153+ TEST (LlvmLibcWcsnrtombs, InvalidState) {
154+ LIBC_NAMESPACE::internal::mbstate state;
155+ state.total_bytes = 100 ;
156+
157+ const wchar_t src[] = {static_cast <wchar_t >(0x1f921 ),
158+ static_cast <wchar_t >(0x2211 ),
159+ static_cast <wchar_t >(0xff ), static_cast <wchar_t >(0x41 ),
160+ static_cast <wchar_t >(0x0 )};
161+ const wchar_t *cur = src;
162+
163+ // n parameter ignored when dest is null
164+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs (nullptr , &cur, 5 , 1 , &state);
165+ ASSERT_FALSE (res.has_value ());
166+ ASSERT_EQ (res.error (), EINVAL);
167+ }
168+
169+ TEST (LlvmLibcWcsnrtombs, InvalidCharacter) {
110170 LIBC_NAMESPACE::internal::mbstate state1;
111171
112172 const wchar_t src[] = {static_cast <wchar_t >(0x1f921 ),
113173 static_cast <wchar_t >(0x2211 ),
114174 static_cast <wchar_t >(0x12ffff ), // invalid widechar
115175 static_cast <wchar_t >(0x0 )};
116176 const wchar_t *cur = src;
177+ char mbs[11 ];
117178
118179 // n parameter ignored when dest is null
119- auto res = LIBC_NAMESPACE::internal::wcsnrtombs (nullptr , &cur, 5 , 7 , &state1);
180+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs (mbs , &cur, 5 , 7 , &state1);
120181 ASSERT_TRUE (res.has_value ());
121182 ASSERT_EQ (res.value (), static_cast <size_t >(7 ));
122183
123184 LIBC_NAMESPACE::internal::mbstate state2;
124185 cur = src;
125- res = LIBC_NAMESPACE::internal::wcsnrtombs (nullptr , &cur, 5 , 100 , &state2);
186+ res = LIBC_NAMESPACE::internal::wcsnrtombs (mbs , &cur, 5 , 11 , &state2);
126187 ASSERT_FALSE (res.has_value ());
127188 ASSERT_EQ (res.error (), EILSEQ);
128189}
0 commit comments