1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <gtest/gtest.h> 18 19 #include <errno.h> 20 #include <inttypes.h> 21 #include <limits.h> 22 #include <locale.h> 23 #include <math.h> 24 #include <stdint.h> 25 #include <sys/cdefs.h> 26 #include <wchar.h> 27 28 #include "utils.h" 29 30 #define NUM_WCHARS(num_bytes) ((num_bytes)/sizeof(wchar_t)) 31 TEST(wchar,sizeof_wchar_t)32 TEST(wchar, sizeof_wchar_t) { 33 EXPECT_EQ(4U, sizeof(wchar_t)); 34 EXPECT_EQ(4U, sizeof(wint_t)); 35 } 36 TEST(wchar,mbrlen)37 TEST(wchar, mbrlen) { 38 char bytes[] = { 'h', 'e', 'l', 'l', 'o', '\0' }; 39 EXPECT_EQ(0U, mbrlen(&bytes[0], 0, nullptr)); 40 EXPECT_EQ(1U, mbrlen(&bytes[0], 1, nullptr)); 41 42 EXPECT_EQ(1U, mbrlen(&bytes[4], 1, nullptr)); 43 EXPECT_EQ(0U, mbrlen(&bytes[5], 1, nullptr)); 44 } 45 TEST(wchar,wctomb_wcrtomb)46 TEST(wchar, wctomb_wcrtomb) { 47 // wctomb and wcrtomb behave differently when s == NULL. 48 EXPECT_EQ(0, wctomb(nullptr, L'h')); 49 EXPECT_EQ(0, wctomb(nullptr, L'\0')); 50 EXPECT_EQ(1U, wcrtomb(nullptr, L'\0', nullptr)); 51 EXPECT_EQ(1U, wcrtomb(nullptr, L'h', nullptr)); 52 53 char bytes[MB_LEN_MAX]; 54 55 // wctomb and wcrtomb behave similarly for the null wide character. 56 EXPECT_EQ(1, wctomb(bytes, L'\0')); 57 EXPECT_EQ(1U, wcrtomb(bytes, L'\0', nullptr)); 58 59 // ...and for regular characters. 60 memset(bytes, 0, sizeof(bytes)); 61 EXPECT_EQ(1, wctomb(bytes, L'h')); 62 EXPECT_EQ('h', bytes[0]); 63 memset(bytes, 0, sizeof(bytes)); 64 EXPECT_EQ(1U, wcrtomb(bytes, L'h', nullptr)); 65 EXPECT_EQ('h', bytes[0]); 66 67 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 68 uselocale(LC_GLOBAL_LOCALE); 69 70 // 1-byte UTF-8. 71 memset(bytes, 0, sizeof(bytes)); 72 EXPECT_EQ(1U, wcrtomb(bytes, L'h', nullptr)); 73 EXPECT_EQ('h', bytes[0]); 74 // 2-byte UTF-8. 75 memset(bytes, 0, sizeof(bytes)); 76 EXPECT_EQ(2U, wcrtomb(bytes, 0x00a2, nullptr)); 77 EXPECT_EQ('\xc2', bytes[0]); 78 EXPECT_EQ('\xa2', bytes[1]); 79 // 3-byte UTF-8. 80 memset(bytes, 0, sizeof(bytes)); 81 EXPECT_EQ(3U, wcrtomb(bytes, 0x20ac, nullptr)); 82 EXPECT_EQ('\xe2', bytes[0]); 83 EXPECT_EQ('\x82', bytes[1]); 84 EXPECT_EQ('\xac', bytes[2]); 85 // 4-byte UTF-8. 86 memset(bytes, 0, sizeof(bytes)); 87 EXPECT_EQ(4U, wcrtomb(bytes, 0x24b62, nullptr)); 88 EXPECT_EQ('\xf0', bytes[0]); 89 EXPECT_EQ('\xa4', bytes[1]); 90 EXPECT_EQ('\xad', bytes[2]); 91 EXPECT_EQ('\xa2', bytes[3]); 92 // Invalid code point. 93 EXPECT_EQ(static_cast<size_t>(-1), wcrtomb(bytes, 0xffffffff, nullptr)); 94 EXPECT_EQ(EILSEQ, errno); 95 } 96 TEST(wchar,wcrtomb_start_state)97 TEST(wchar, wcrtomb_start_state) { 98 char out[MB_LEN_MAX]; 99 mbstate_t ps; 100 101 // Any non-initial state is invalid when calling wcrtomb. 102 memset(&ps, 0, sizeof(ps)); 103 EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps)); 104 EXPECT_EQ(static_cast<size_t>(-1), wcrtomb(out, 0x00a2, &ps)); 105 EXPECT_EQ(EILSEQ, errno); 106 107 // If the first argument to wcrtomb is NULL or the second is L'\0' the shift 108 // state should be reset. 109 memset(&ps, 0, sizeof(ps)); 110 EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps)); 111 EXPECT_EQ(1U, wcrtomb(nullptr, 0x00a2, &ps)); 112 EXPECT_TRUE(mbsinit(&ps)); 113 114 memset(&ps, 0, sizeof(ps)); 115 EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xf0\xa4", 1, &ps)); 116 EXPECT_EQ(1U, wcrtomb(out, L'\0', &ps)); 117 EXPECT_TRUE(mbsinit(&ps)); 118 } 119 TEST(wchar,wcstombs_wcrtombs)120 TEST(wchar, wcstombs_wcrtombs) { 121 const wchar_t chars[] = { L'h', L'e', L'l', L'l', L'o', 0 }; 122 const wchar_t bad_chars[] = { L'h', L'i', static_cast<wchar_t>(0xffffffff), 0 }; 123 const wchar_t* src; 124 char bytes[BUFSIZ]; 125 126 // Given a NULL destination, these functions count valid characters. 127 EXPECT_EQ(5U, wcstombs(nullptr, chars, 0)); 128 EXPECT_EQ(5U, wcstombs(nullptr, chars, 4)); 129 EXPECT_EQ(5U, wcstombs(nullptr, chars, 256)); 130 src = chars; 131 EXPECT_EQ(5U, wcsrtombs(nullptr, &src, 0, nullptr)); 132 EXPECT_EQ(&chars[0], src); 133 src = chars; 134 EXPECT_EQ(5U, wcsrtombs(nullptr, &src, 4, nullptr)); 135 EXPECT_EQ(&chars[0], src); 136 src = chars; 137 EXPECT_EQ(5U, wcsrtombs(nullptr, &src, 256, nullptr)); 138 EXPECT_EQ(&chars[0], src); 139 140 // An unrepresentable char just returns an error from wcstombs... 141 errno = 0; 142 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(nullptr, bad_chars, 0)); 143 EXPECT_EQ(EILSEQ, errno); 144 errno = 0; 145 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(nullptr, bad_chars, 256)); 146 EXPECT_EQ(EILSEQ, errno); 147 148 // And wcsrtombs doesn't tell us where it got stuck because we didn't ask it 149 // to actually convert anything... 150 errno = 0; 151 src = bad_chars; 152 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(nullptr, &src, 0, nullptr)); 153 EXPECT_EQ(&bad_chars[0], src); 154 EXPECT_EQ(EILSEQ, errno); 155 errno = 0; 156 src = bad_chars; 157 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(nullptr, &src, 256, nullptr)); 158 EXPECT_EQ(&bad_chars[0], src); 159 EXPECT_EQ(EILSEQ, errno); 160 161 // Okay, now let's test actually converting something... 162 memset(bytes, 'x', sizeof(bytes)); 163 EXPECT_EQ(0U, wcstombs(bytes, chars, 0)); 164 memset(bytes, 'x', sizeof(bytes)); 165 EXPECT_EQ(4U, wcstombs(bytes, chars, 4)); 166 bytes[5] = 0; 167 EXPECT_STREQ("hellx", bytes); 168 memset(bytes, 'x', sizeof(bytes)); 169 EXPECT_EQ(5U, wcstombs(bytes, chars, 256)); 170 EXPECT_STREQ("hello", bytes); 171 memset(bytes, 'x', sizeof(bytes)); 172 EXPECT_EQ(5U, wcstombs(bytes, chars, 6)); 173 EXPECT_STREQ("hello", bytes); 174 errno = 0; 175 memset(bytes, 'x', sizeof(bytes)); 176 EXPECT_EQ(static_cast<size_t>(-1), wcstombs(bytes, bad_chars, 256)); 177 EXPECT_EQ(EILSEQ, errno); 178 bytes[3] = 0; 179 EXPECT_STREQ("hix", bytes); 180 181 // wcsrtombs is a bit more informative... 182 memset(bytes, 'x', sizeof(bytes)); 183 src = chars; 184 EXPECT_EQ(0U, wcsrtombs(bytes, &src, 0, nullptr)); 185 EXPECT_EQ(&chars[0], src); // No input consumed. 186 EXPECT_EQ(EILSEQ, errno); 187 188 memset(bytes, 'x', sizeof(bytes)); 189 src = chars; 190 EXPECT_EQ(4U, wcsrtombs(bytes, &src, 4, nullptr)); 191 EXPECT_EQ(&chars[4], src); // Some input consumed. 192 EXPECT_EQ(EILSEQ, errno); 193 bytes[5] = 0; 194 EXPECT_STREQ("hellx", bytes); 195 196 memset(bytes, 'x', sizeof(bytes)); 197 src = chars; 198 EXPECT_EQ(5U, wcsrtombs(bytes, &src, 256, nullptr)); 199 EXPECT_EQ(nullptr, src); // All input consumed! 200 EXPECT_EQ(EILSEQ, errno); 201 EXPECT_STREQ("hello", bytes); 202 203 memset(bytes, 'x', sizeof(bytes)); 204 src = chars; 205 EXPECT_EQ(5U, wcsrtombs(bytes, &src, 6, nullptr)); 206 EXPECT_EQ(nullptr, src); // All input consumed. 207 EXPECT_EQ(EILSEQ, errno); 208 EXPECT_STREQ("hello", bytes); 209 210 memset(bytes, 'x', sizeof(bytes)); 211 src = bad_chars; 212 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(bytes, &src, 256, nullptr)); 213 EXPECT_EQ(&bad_chars[2], src); 214 EXPECT_EQ(EILSEQ, errno); 215 bytes[3] = 0; 216 EXPECT_STREQ("hix", bytes); 217 218 // Any non-initial state is invalid when calling wcsrtombs. 219 mbstate_t ps; 220 src = chars; 221 memset(&ps, 0, sizeof(ps)); 222 ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps)); 223 EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(nullptr, &src, 0, &ps)); 224 EXPECT_EQ(EILSEQ, errno); 225 } 226 TEST(wchar,limits)227 TEST(wchar, limits) { 228 ASSERT_LT(WCHAR_MIN, WCHAR_MAX); 229 } 230 TEST(wchar,wcsstr)231 TEST(wchar, wcsstr) { 232 const wchar_t* haystack = L"big daddy/giant haystacks!"; 233 const wchar_t* empty_haystack = L""; 234 235 // The empty needle is a special case. 236 ASSERT_EQ(haystack, wcsstr(haystack, L"")); 237 ASSERT_EQ(empty_haystack, wcsstr(empty_haystack, L"")); 238 239 ASSERT_EQ(haystack, wcsstr(haystack, L"b")); 240 ASSERT_EQ(haystack, wcsstr(haystack, L"big")); 241 ASSERT_EQ(haystack + 9, wcsstr(haystack, L"/")); 242 ASSERT_EQ(haystack + 9, wcsstr(haystack, L"/giant")); 243 ASSERT_EQ(haystack + 25, wcsstr(haystack, L"!")); 244 ASSERT_EQ(haystack + 19, wcsstr(haystack, L"stacks!")); 245 246 ASSERT_EQ(nullptr, wcsstr(haystack, L"monkey")); 247 ASSERT_EQ(nullptr, wcsstr(empty_haystack, L"monkey")); 248 } 249 TEST(wchar,wcsstr_80199)250 TEST(wchar, wcsstr_80199) { 251 // https://code.google.com/p/android/issues/detail?id=80199 252 ASSERT_TRUE(wcsstr(L"romrom", L"rom") != nullptr); 253 } 254 TEST(wchar,mbtowc)255 TEST(wchar, mbtowc) { 256 wchar_t out[8]; 257 258 out[0] = 'x'; 259 ASSERT_EQ(0, mbtowc(out, "hello", 0)); 260 ASSERT_EQ('x', out[0]); 261 262 ASSERT_EQ(0, mbtowc(out, "hello", 0)); 263 ASSERT_EQ(0, mbtowc(out, "", 0)); 264 ASSERT_EQ(1, mbtowc(out, "hello", 1)); 265 ASSERT_EQ(L'h', out[0]); 266 267 ASSERT_EQ(0, mbtowc(nullptr, "hello", 0)); 268 ASSERT_EQ(0, mbtowc(nullptr, "", 0)); 269 ASSERT_EQ(1, mbtowc(nullptr, "hello", 1)); 270 271 ASSERT_EQ(0, mbtowc(nullptr, nullptr, 0)); 272 } 273 TEST(wchar,mbrtowc)274 TEST(wchar, mbrtowc) { 275 wchar_t out[8]; 276 277 out[0] = 'x'; 278 ASSERT_EQ(0U, mbrtowc(out, "hello", 0, nullptr)); 279 ASSERT_EQ('x', out[0]); 280 281 ASSERT_EQ(0U, mbrtowc(out, "hello", 0, nullptr)); 282 ASSERT_EQ(0U, mbrtowc(out, "", 0, nullptr)); 283 ASSERT_EQ(1U, mbrtowc(out, "hello", 1, nullptr)); 284 ASSERT_EQ(L'h', out[0]); 285 286 ASSERT_EQ(0U, mbrtowc(nullptr, "hello", 0, nullptr)); 287 ASSERT_EQ(0U, mbrtowc(nullptr, "", 0, nullptr)); 288 ASSERT_EQ(1U, mbrtowc(nullptr, "hello", 1, nullptr)); 289 290 ASSERT_EQ(0U, mbrtowc(nullptr, nullptr, 0, nullptr)); 291 292 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 293 uselocale(LC_GLOBAL_LOCALE); 294 295 // 1-byte UTF-8. 296 ASSERT_EQ(1U, mbrtowc(out, "abcdef", 6, nullptr)); 297 ASSERT_EQ(L'a', out[0]); 298 // 2-byte UTF-8. 299 ASSERT_EQ(2U, mbrtowc(out, "\xc2\xa2" "cdef", 6, nullptr)); 300 ASSERT_EQ(static_cast<wchar_t>(0x00a2), out[0]); 301 // 3-byte UTF-8. 302 ASSERT_EQ(3U, mbrtowc(out, "\xe2\x82\xac" "def", 6, nullptr)); 303 ASSERT_EQ(static_cast<wchar_t>(0x20ac), out[0]); 304 // 4-byte UTF-8. 305 ASSERT_EQ(4U, mbrtowc(out, "\xf0\xa4\xad\xa2" "ef", 6, nullptr)); 306 ASSERT_EQ(static_cast<wchar_t>(0x24b62), out[0]); 307 #if defined(__BIONIC__) // glibc allows this. 308 // Illegal 5-byte UTF-8. 309 ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf8\xa1\xa2\xa3\xa4" "f", 6, nullptr)); 310 ASSERT_EQ(EILSEQ, errno); 311 #endif 312 // Illegal over-long sequence. 313 ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf0\x82\x82\xac" "ef", 6, nullptr)); 314 ASSERT_EQ(EILSEQ, errno); 315 } 316 TEST(wchar,mbrtowc_valid_non_characters)317 TEST(wchar, mbrtowc_valid_non_characters) { 318 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 319 uselocale(LC_GLOBAL_LOCALE); 320 321 wchar_t out[8] = {}; 322 323 ASSERT_EQ(3U, mbrtowc(out, "\xef\xbf\xbe", 3, nullptr)); 324 ASSERT_EQ(static_cast<wchar_t>(0xfffe), out[0]); 325 ASSERT_EQ(3U, mbrtowc(out, "\xef\xbf\xbf", 3, nullptr)); 326 ASSERT_EQ(static_cast<wchar_t>(0xffff), out[0]); 327 } 328 TEST(wchar,mbrtowc_out_of_range)329 TEST(wchar, mbrtowc_out_of_range) { 330 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 331 uselocale(LC_GLOBAL_LOCALE); 332 333 wchar_t out[8] = {}; 334 errno = 0; 335 ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf5\x80\x80\x80", 4, nullptr)); 336 ASSERT_EQ(EILSEQ, errno); 337 } 338 test_mbrtowc_incomplete(mbstate_t * ps)339 static void test_mbrtowc_incomplete(mbstate_t* ps) { 340 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 341 uselocale(LC_GLOBAL_LOCALE); 342 343 wchar_t out; 344 // 2-byte UTF-8. 345 ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xc2", 1, ps)); 346 ASSERT_EQ(1U, mbrtowc(&out, "\xa2" "cdef", 5, ps)); 347 ASSERT_EQ(static_cast<wchar_t>(0x00a2), out); 348 ASSERT_TRUE(mbsinit(ps)); 349 // 3-byte UTF-8. 350 ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xe2", 1, ps)); 351 ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\x82", 1, ps)); 352 ASSERT_EQ(1U, mbrtowc(&out, "\xac" "def", 4, ps)); 353 ASSERT_EQ(static_cast<wchar_t>(0x20ac), out); 354 ASSERT_TRUE(mbsinit(ps)); 355 // 4-byte UTF-8. 356 ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xf0", 1, ps)); 357 ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xa4\xad", 2, ps)); 358 ASSERT_EQ(1U, mbrtowc(&out, "\xa2" "ef", 3, ps)); 359 ASSERT_EQ(static_cast<wchar_t>(0x24b62), out); 360 ASSERT_TRUE(mbsinit(ps)); 361 362 // Invalid 2-byte 363 ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xc2", 1, ps)); 364 ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(&out, "\x20" "cdef", 5, ps)); 365 ASSERT_EQ(EILSEQ, errno); 366 } 367 TEST(wchar,mbrtowc_incomplete)368 TEST(wchar, mbrtowc_incomplete) { 369 mbstate_t ps; 370 memset(&ps, 0, sizeof(ps)); 371 372 test_mbrtowc_incomplete(&ps); 373 test_mbrtowc_incomplete(nullptr); 374 } 375 test_mbsrtowcs(mbstate_t * ps)376 static void test_mbsrtowcs(mbstate_t* ps) { 377 constexpr const char* VALID = "A" "\xc2\xa2" "\xe2\x82\xac" "\xf0\xa4\xad\xa2" "ef"; 378 constexpr const char* INVALID = "A" "\xc2\x20" "ef"; 379 constexpr const char* INCOMPLETE = "A" "\xc2"; 380 wchar_t out[4]; 381 382 const char* valid = VALID; 383 ASSERT_EQ(4U, mbsrtowcs(out, &valid, 4, ps)); 384 ASSERT_EQ(L'A', out[0]); 385 ASSERT_EQ(static_cast<wchar_t>(0x00a2), out[1]); 386 ASSERT_EQ(static_cast<wchar_t>(0x20ac), out[2]); 387 ASSERT_EQ(static_cast<wchar_t>(0x24b62), out[3]); 388 // Check that valid has advanced to the next unread character. 389 ASSERT_EQ('e', *valid); 390 391 wmemset(out, L'x', NUM_WCHARS(sizeof(out))); 392 ASSERT_EQ(2U, mbsrtowcs(out, &valid, 4, ps)); 393 ASSERT_EQ(L'e', out[0]); 394 ASSERT_EQ(L'f', out[1]); 395 ASSERT_EQ(L'\0', out[2]); 396 // Check that we didn't clobber the rest of out. 397 ASSERT_EQ(L'x', out[3]); 398 // Check that valid has advanced to the end of the string. 399 ASSERT_EQ(nullptr, valid); 400 401 const char* invalid = INVALID; 402 ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(out, &invalid, 4, ps)); 403 EXPECT_EQ(EILSEQ, errno); 404 ASSERT_EQ('\xc2', *invalid); 405 406 const char* incomplete = INCOMPLETE; 407 ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(out, &incomplete, 2, ps)); 408 EXPECT_EQ(EILSEQ, errno); 409 ASSERT_EQ('\xc2', *incomplete); 410 411 // If dst is null, *src shouldn't be updated. 412 // https://code.google.com/p/android/issues/detail?id=166381 413 const char* mbs = VALID; 414 EXPECT_EQ(6U, mbsrtowcs(nullptr, &mbs, 0, ps)); 415 EXPECT_EQ(VALID, mbs); 416 mbs = INVALID; 417 EXPECT_EQ(static_cast<size_t>(-1), mbsrtowcs(nullptr, &mbs, 0, ps)); 418 EXPECT_EQ(INVALID, mbs); 419 mbs = INCOMPLETE; 420 EXPECT_EQ(static_cast<size_t>(-1), mbsrtowcs(nullptr, &mbs, 0, ps)); 421 EXPECT_EQ(INCOMPLETE, mbs); 422 } 423 TEST(wchar,mbsrtowcs)424 TEST(wchar, mbsrtowcs) { 425 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 426 uselocale(LC_GLOBAL_LOCALE); 427 428 mbstate_t ps; 429 memset(&ps, 0, sizeof(ps)); 430 test_mbsrtowcs(&ps); 431 test_mbsrtowcs(nullptr); 432 433 // Invalid multi byte continuation. 434 const char* invalid = "\x20"; 435 wchar_t out; 436 ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(&out, "\xc2", 1, &ps)); 437 ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(&out, &invalid, 1, &ps)); 438 EXPECT_EQ(EILSEQ, errno); 439 ASSERT_EQ('\x20', *invalid); 440 } 441 442 template <typename T> 443 using WcsToIntFn = T (*)(const wchar_t*, wchar_t**, int); 444 445 template <typename T> TestSingleWcsToInt(WcsToIntFn<T> fn,const wchar_t * str,int base,T expected_value,ptrdiff_t expected_len)446 void TestSingleWcsToInt(WcsToIntFn<T> fn, const wchar_t* str, int base, 447 T expected_value, ptrdiff_t expected_len) { 448 wchar_t* p; 449 ASSERT_EQ(expected_value, fn(str, &p, base)); 450 ASSERT_EQ(expected_len, p - str) << str; 451 } 452 453 template <typename T> TestWcsToInt(WcsToIntFn<T> fn)454 void TestWcsToInt(WcsToIntFn<T> fn) { 455 TestSingleWcsToInt(fn, L"123", 10, static_cast<T>(123), 3); 456 TestSingleWcsToInt(fn, L"123", 0, static_cast<T>(123), 3); 457 TestSingleWcsToInt(fn, L"123#", 10, static_cast<T>(123), 3); 458 TestSingleWcsToInt(fn, L"01000", 8, static_cast<T>(512), 5); 459 TestSingleWcsToInt(fn, L"01000", 0, static_cast<T>(512), 5); 460 TestSingleWcsToInt(fn, L" 123 45", 0, static_cast<T>(123), 6); 461 TestSingleWcsToInt(fn, L" -123", 0, static_cast<T>(-123), 6); 462 TestSingleWcsToInt(fn, L"0x10000", 0, static_cast<T>(65536), 7); 463 TestSingleWcsToInt(fn, L"0b1011", 0, static_cast<T>(0b1011), 6); 464 } 465 466 template <typename T> TestWcsToIntLimits(WcsToIntFn<T> fn,const wchar_t * min_str,const wchar_t * max_str)467 void TestWcsToIntLimits(WcsToIntFn<T> fn, const wchar_t* min_str, 468 const wchar_t* max_str) { 469 if (std::is_signed<T>::value) { 470 ASSERT_EQ(std::numeric_limits<T>::min(), fn(min_str, nullptr, 0)) << min_str; 471 } else { 472 // If the subject sequence begins with a <hyphen-minus>, the value resulting 473 // from the conversion shall be negated. 474 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html 475 ASSERT_EQ(std::numeric_limits<T>::max(), fn(min_str, nullptr, 0)) << min_str; 476 } 477 ASSERT_EQ(std::numeric_limits<T>::max(), fn(max_str, nullptr, 0)) << max_str; 478 } 479 TEST(wchar,wcstol)480 TEST(wchar, wcstol) { 481 TestWcsToInt(wcstol); 482 } 483 TEST(wchar,wcstol_limits)484 TEST(wchar, wcstol_limits) { 485 if (sizeof(long) == 8) { 486 TestWcsToIntLimits(wcstol, L"-9223372036854775809", L"9223372036854775808"); 487 } else { 488 TestWcsToIntLimits(wcstol, L"-2147483649", L"2147483648"); 489 } 490 } 491 TEST(wchar,wcstoul)492 TEST(wchar, wcstoul) { 493 TestWcsToInt(wcstoul); 494 } 495 TEST(wchar,wcstoul_limits)496 TEST(wchar, wcstoul_limits) { 497 if (sizeof(long) == 8) { 498 TestWcsToIntLimits(wcstoul, L"-1", L"18446744073709551616"); 499 } else { 500 TestWcsToIntLimits(wcstoul, L"-1", L"4294967296"); 501 } 502 } 503 TEST(wchar,wcstoll)504 TEST(wchar, wcstoll) { 505 TestWcsToInt(wcstoll); 506 } 507 TEST(wchar,wcstoll_limits)508 TEST(wchar, wcstoll_limits) { 509 TestWcsToIntLimits(wcstoll, L"-9223372036854775809", L"9223372036854775808"); 510 } 511 TEST(wchar,wcstoull)512 TEST(wchar, wcstoull) { 513 TestWcsToInt(wcstoull); 514 } 515 TEST(wchar,wcstoull_limits)516 TEST(wchar, wcstoull_limits) { 517 TestWcsToIntLimits(wcstoull, L"-1", L"18446744073709551616"); 518 } 519 TEST(wchar,wcstoimax)520 TEST(wchar, wcstoimax) { 521 TestWcsToInt(wcstoimax); 522 } 523 TEST(wchar,wcstoimax_limits)524 TEST(wchar, wcstoimax_limits) { 525 TestWcsToIntLimits(wcstoimax, L"-9223372036854775809", 526 L"9223372036854775808"); 527 } 528 TEST(wchar,wcstoumax)529 TEST(wchar, wcstoumax) { 530 TestWcsToInt(wcstoumax); 531 } 532 TEST(wchar,wcstoumax_limits)533 TEST(wchar, wcstoumax_limits) { 534 TestWcsToIntLimits(wcstoumax, L"-1", L"18446744073709551616"); 535 } 536 TEST(wchar,mbsnrtowcs)537 TEST(wchar, mbsnrtowcs) { 538 wchar_t dst[128]; 539 const char* s = "hello, world!"; 540 const char* src; 541 542 memset(dst, 0, sizeof(dst)); 543 src = s; 544 ASSERT_EQ(0U, mbsnrtowcs(dst, &src, 0, 0, nullptr)); 545 546 memset(dst, 0, sizeof(dst)); 547 src = s; 548 ASSERT_EQ(2U, mbsnrtowcs(dst, &src, 2, 123, nullptr)); // glibc chokes on SIZE_MAX here. 549 ASSERT_EQ(L'h', dst[0]); 550 ASSERT_EQ(L'e', dst[1]); 551 ASSERT_EQ(&s[2], src); 552 553 memset(dst, 0, sizeof(dst)); 554 src = s; 555 ASSERT_EQ(3U, mbsnrtowcs(dst, &src, SIZE_MAX, 3, nullptr)); 556 ASSERT_EQ(L'h', dst[0]); 557 ASSERT_EQ(L'e', dst[1]); 558 ASSERT_EQ(L'l', dst[2]); 559 ASSERT_EQ(&s[3], src); 560 561 memset(dst, 0, sizeof(dst)); 562 const char* incomplete = "\xc2"; // Incomplete UTF-8 sequence. 563 src = incomplete; 564 errno = 0; 565 ASSERT_EQ(static_cast<size_t>(-1), mbsnrtowcs(dst, &src, SIZE_MAX, 3, nullptr)); 566 ASSERT_EQ(EILSEQ, errno); 567 568 src = incomplete; 569 errno = 0; 570 ASSERT_EQ(static_cast<size_t>(-1), mbsnrtowcs(nullptr, &src, SIZE_MAX, 3, nullptr)); 571 ASSERT_EQ(EILSEQ, errno); 572 } 573 TEST(wchar,wcsftime__wcsftime_l)574 TEST(wchar, wcsftime__wcsftime_l) { 575 setenv("TZ", "UTC", 1); 576 577 struct tm t; 578 memset(&t, 0, sizeof(tm)); 579 t.tm_year = 200; 580 t.tm_mon = 2; 581 t.tm_mday = 10; 582 583 wchar_t buf[64]; 584 585 EXPECT_EQ(24U, wcsftime(buf, sizeof(buf), L"%c", &t)); 586 EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf); 587 EXPECT_EQ(24U, wcsftime_l(buf, sizeof(buf), L"%c", &t, LC_GLOBAL_LOCALE)); 588 EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf); 589 } 590 TEST(wchar,wmemmove_smoke)591 TEST(wchar, wmemmove_smoke) { 592 const wchar_t const_wstr[] = L"This is a test of something or other....."; 593 wchar_t wstr[NUM_WCHARS(sizeof(const_wstr))]; 594 595 EXPECT_EQ(wstr, wmemmove(wstr, const_wstr, NUM_WCHARS(sizeof(const_wstr)))); 596 EXPECT_STREQ(const_wstr, wstr); 597 598 EXPECT_EQ(wstr+5, wmemmove(wstr+5, wstr, NUM_WCHARS(sizeof(const_wstr)) - 6)); 599 EXPECT_STREQ(L"This This is a test of something or other", wstr); 600 } 601 TEST(wchar,wmemcpy_smoke)602 TEST(wchar, wmemcpy_smoke) { 603 const wchar_t src[] = L"Source string"; 604 wchar_t dst[NUM_WCHARS(sizeof(src))]; 605 606 EXPECT_EQ(dst, wmemcpy(dst, src, NUM_WCHARS(sizeof(src)))); 607 EXPECT_STREQ(dst, src); 608 } 609 TEST(wchar,wcpcpy_smoke)610 TEST(wchar, wcpcpy_smoke) { 611 const wchar_t src[] = L"Source string"; 612 wchar_t dst[NUM_WCHARS(sizeof(src))]; 613 614 EXPECT_EQ(dst + NUM_WCHARS(sizeof(src)) - 1, wcpcpy(dst, src)); 615 EXPECT_STREQ(dst, src); 616 } 617 TEST(wchar,wcpncpy_smoke)618 TEST(wchar, wcpncpy_smoke) { 619 const wchar_t src[] = L"Source string"; 620 wchar_t dst[NUM_WCHARS(sizeof(src)) + 5]; 621 622 size_t src_len = NUM_WCHARS(sizeof(src)) - 1; 623 EXPECT_EQ(dst + src_len, wcpncpy(dst, src, src_len + 1)); 624 EXPECT_STREQ(dst, src); 625 626 EXPECT_EQ(dst + 6, wcpncpy(dst, src, 6)); 627 dst[6] = L'\0'; 628 EXPECT_STREQ(dst, L"Source"); 629 630 wmemset(dst, L'x', NUM_WCHARS(sizeof(dst))); 631 EXPECT_EQ(dst + src_len, wcpncpy(dst, src, src_len + 4)); 632 EXPECT_STREQ(dst, src); 633 EXPECT_EQ(dst[src_len], L'\0'); 634 EXPECT_EQ(dst[src_len+1], L'\0'); 635 EXPECT_EQ(dst[src_len+2], L'\0'); 636 EXPECT_EQ(dst[src_len+3], L'\0'); 637 EXPECT_EQ(dst[src_len+4], L'x'); 638 } 639 TEST(wchar,wcscpy_smoke)640 TEST(wchar, wcscpy_smoke) { 641 const wchar_t src[] = L"Source string"; 642 wchar_t dst[NUM_WCHARS(sizeof(src))]; 643 644 EXPECT_EQ(dst, wcscpy(dst, src)); 645 EXPECT_STREQ(src, dst); 646 } 647 TEST(wchar,wcsncpy_smoke)648 TEST(wchar, wcsncpy_smoke) { 649 const wchar_t src[] = L"Source string"; 650 wchar_t dst[NUM_WCHARS(sizeof(src)) + 5]; 651 652 size_t src_len = NUM_WCHARS(sizeof(src)) - 1; 653 EXPECT_EQ(dst, wcsncpy(dst, src, src_len + 1)); 654 EXPECT_STREQ(dst, src); 655 656 EXPECT_EQ(dst, wcsncpy(dst, src, 6)); 657 dst[6] = L'\0'; 658 EXPECT_STREQ(dst, L"Source"); 659 EXPECT_EQ(dst, wcsncpy(dst, L"clobber", 0)); 660 EXPECT_STREQ(dst, L"Source"); 661 662 wmemset(dst, L'x', NUM_WCHARS(sizeof(dst))); 663 EXPECT_EQ(dst, wcsncpy(dst, src, src_len + 4)); 664 EXPECT_STREQ(dst, src); 665 EXPECT_EQ(dst[src_len], L'\0'); 666 EXPECT_EQ(dst[src_len+1], L'\0'); 667 EXPECT_EQ(dst[src_len+2], L'\0'); 668 EXPECT_EQ(dst[src_len+3], L'\0'); 669 EXPECT_EQ(dst[src_len+4], L'x'); 670 } 671 TEST(wchar,mbrtowc_15439554)672 TEST(wchar, mbrtowc_15439554) { 673 // http://b/15439554 674 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 675 uselocale(LC_GLOBAL_LOCALE); 676 677 ASSERT_GE(static_cast<size_t>(MB_LEN_MAX), MB_CUR_MAX); 678 ASSERT_GE(MB_CUR_MAX, 4U); 679 680 wchar_t wc; 681 size_t n; 682 683 // 1-byte character. 684 n = mbrtowc(&wc, "x", MB_CUR_MAX, nullptr); 685 EXPECT_EQ(1U, n); 686 EXPECT_EQ(L'x', wc); 687 // 2-byte character. 688 n = mbrtowc(&wc, "\xc2\xa2", MB_CUR_MAX, nullptr); 689 EXPECT_EQ(2U, n); 690 EXPECT_EQ(L'¢', wc); 691 // 3-byte character. 692 n = mbrtowc(&wc, "\xe2\x82\xac", MB_CUR_MAX, nullptr); 693 EXPECT_EQ(3U, n); 694 EXPECT_EQ(L'€', wc); 695 // 4-byte character. 696 n = mbrtowc(&wc, "\xf0\xa4\xad\xa2", MB_CUR_MAX, nullptr); 697 EXPECT_EQ(4U, n); 698 EXPECT_EQ(L'��', wc); 699 } 700 TEST(wchar,open_wmemstream)701 TEST(wchar, open_wmemstream) { 702 wchar_t* p = nullptr; 703 size_t size = 0; 704 FILE* fp = open_wmemstream(&p, &size); 705 ASSERT_NE(EOF, fputws(L"hello, world!", fp)); 706 fclose(fp); 707 708 ASSERT_STREQ(L"hello, world!", p); 709 ASSERT_EQ(wcslen(L"hello, world!"), size); 710 free(p); 711 } 712 TEST(stdio,open_wmemstream_EINVAL)713 TEST(stdio, open_wmemstream_EINVAL) { 714 #if defined(__BIONIC__) 715 wchar_t* p; 716 size_t size; 717 #pragma clang diagnostic push 718 #pragma clang diagnostic ignored "-Wnonnull" 719 // Invalid buffer. 720 errno = 0; 721 ASSERT_EQ(nullptr, open_wmemstream(nullptr, &size)); 722 ASSERT_EQ(EINVAL, errno); 723 724 // Invalid size. 725 errno = 0; 726 ASSERT_EQ(nullptr, open_wmemstream(&p, nullptr)); 727 ASSERT_EQ(EINVAL, errno); 728 #pragma clang diagnostic pop 729 #else 730 GTEST_SKIP() << "This test is bionic-specific"; 731 #endif 732 } 733 TEST(wchar,wcstol_EINVAL)734 TEST(wchar, wcstol_EINVAL) { 735 errno = 0; 736 wcstol(L"123", nullptr, -1); 737 ASSERT_EQ(EINVAL, errno); 738 errno = 0; 739 wcstol(L"123", nullptr, 1); 740 ASSERT_EQ(EINVAL, errno); 741 errno = 0; 742 wcstol(L"123", nullptr, 37); 743 ASSERT_EQ(EINVAL, errno); 744 } 745 TEST(wchar,wcstoll_EINVAL)746 TEST(wchar, wcstoll_EINVAL) { 747 errno = 0; 748 wcstoll(L"123", nullptr, -1); 749 ASSERT_EQ(EINVAL, errno); 750 errno = 0; 751 wcstoll(L"123", nullptr, 1); 752 ASSERT_EQ(EINVAL, errno); 753 errno = 0; 754 wcstoll(L"123", nullptr, 37); 755 ASSERT_EQ(EINVAL, errno); 756 } 757 TEST(wchar,wcstoul_EINVAL)758 TEST(wchar, wcstoul_EINVAL) { 759 errno = 0; 760 wcstoul(L"123", nullptr, -1); 761 ASSERT_EQ(EINVAL, errno); 762 errno = 0; 763 wcstoul(L"123", nullptr, 1); 764 ASSERT_EQ(EINVAL, errno); 765 errno = 0; 766 wcstoul(L"123", nullptr, 37); 767 ASSERT_EQ(EINVAL, errno); 768 } 769 TEST(wchar,wcstoull_EINVAL)770 TEST(wchar, wcstoull_EINVAL) { 771 errno = 0; 772 wcstoull(L"123", nullptr, -1); 773 ASSERT_EQ(EINVAL, errno); 774 errno = 0; 775 wcstoull(L"123", nullptr, 1); 776 ASSERT_EQ(EINVAL, errno); 777 errno = 0; 778 wcstoull(L"123", nullptr, 37); 779 ASSERT_EQ(EINVAL, errno); 780 } 781 TEST(wchar,wcstoll_l_EINVAL)782 TEST(wchar, wcstoll_l_EINVAL) { 783 errno = 0; 784 wcstoll_l(L"123", nullptr, -1, LC_GLOBAL_LOCALE); 785 ASSERT_EQ(EINVAL, errno); 786 errno = 0; 787 wcstoll_l(L"123", nullptr, 1, LC_GLOBAL_LOCALE); 788 ASSERT_EQ(EINVAL, errno); 789 errno = 0; 790 wcstoll_l(L"123", nullptr, 37, LC_GLOBAL_LOCALE); 791 ASSERT_EQ(EINVAL, errno); 792 } 793 TEST(wchar,wcstoull_l_EINVAL)794 TEST(wchar, wcstoull_l_EINVAL) { 795 errno = 0; 796 wcstoull_l(L"123", nullptr, -1, LC_GLOBAL_LOCALE); 797 ASSERT_EQ(EINVAL, errno); 798 errno = 0; 799 wcstoull_l(L"123", nullptr, 1, LC_GLOBAL_LOCALE); 800 ASSERT_EQ(EINVAL, errno); 801 errno = 0; 802 wcstoull_l(L"123", nullptr, 37, LC_GLOBAL_LOCALE); 803 ASSERT_EQ(EINVAL, errno); 804 } 805 TEST(wchar,wmempcpy)806 TEST(wchar, wmempcpy) { 807 #if !defined(ANDROID_HOST_MUSL) 808 wchar_t dst[6]; 809 ASSERT_EQ(&dst[4], wmempcpy(dst, L"hello", 4)); 810 #else 811 GTEST_SKIP() << "musl doesn't have wmempcpy"; 812 #endif 813 } 814 815 template <typename T> 816 using WcsToFloatFn = T (*)(const wchar_t*, wchar_t**); 817 818 template <typename T> TestSingleWcsToFloat(WcsToFloatFn<T> fn,const wchar_t * str,T expected_value,ptrdiff_t expected_len)819 void TestSingleWcsToFloat(WcsToFloatFn<T> fn, const wchar_t* str, 820 T expected_value, ptrdiff_t expected_len) { 821 wchar_t* p; 822 ASSERT_EQ(expected_value, fn(str, &p)); 823 ASSERT_EQ(expected_len, p - str); 824 } 825 826 template <typename T> TestWcsToFloat(WcsToFloatFn<T> fn)827 void TestWcsToFloat(WcsToFloatFn<T> fn) { 828 TestSingleWcsToFloat(fn, L"123", static_cast<T>(123.0L), 3); 829 TestSingleWcsToFloat(fn, L"123#", static_cast<T>(123.0L), 3); 830 TestSingleWcsToFloat(fn, L" 123 45", static_cast<T>(123.0L), 6); 831 TestSingleWcsToFloat(fn, L"9.0", static_cast<T>(9.0L), 3); 832 TestSingleWcsToFloat(fn, L"-9.0", static_cast<T>(-9.0L), 4); 833 TestSingleWcsToFloat(fn, L" \t\v\f\r\n9.0", static_cast<T>(9.0L), 9); 834 } 835 836 template <typename T> TestWcsToFloatHexFloats(WcsToFloatFn<T> fn)837 void TestWcsToFloatHexFloats(WcsToFloatFn<T> fn) { 838 TestSingleWcsToFloat(fn, L"0.9e1", static_cast<T>(9.0L), 5); 839 TestSingleWcsToFloat(fn, L"0x1.2p3", static_cast<T>(9.0L), 7); 840 TestSingleWcsToFloat(fn, L"+1e+100", static_cast<T>(1e100L), 7); 841 TestSingleWcsToFloat(fn, L"0x10000.80", static_cast<T>(65536.50L), 10); 842 } 843 844 template <typename T> TestWcsToFloatInfNan(WcsToFloatFn<T> fn)845 void TestWcsToFloatInfNan(WcsToFloatFn<T> fn) { 846 ASSERT_TRUE(isnan(fn(L"+nan", nullptr))); 847 ASSERT_TRUE(isnan(fn(L"nan", nullptr))); 848 ASSERT_TRUE(isnan(fn(L"-nan", nullptr))); 849 850 ASSERT_TRUE(isnan(fn(L"+nan(0xff)", nullptr))); 851 ASSERT_TRUE(isnan(fn(L"nan(0xff)", nullptr))); 852 ASSERT_TRUE(isnan(fn(L"-nan(0xff)", nullptr))); 853 854 wchar_t* p; 855 ASSERT_TRUE(isnan(fn(L"+nanny", &p))); 856 ASSERT_STREQ(L"ny", p); 857 ASSERT_TRUE(isnan(fn(L"nanny", &p))); 858 ASSERT_STREQ(L"ny", p); 859 ASSERT_TRUE(isnan(fn(L"-nanny", &p))); 860 ASSERT_STREQ(L"ny", p); 861 862 ASSERT_EQ(0, fn(L"muppet", &p)); 863 ASSERT_STREQ(L"muppet", p); 864 ASSERT_EQ(0, fn(L" muppet", &p)); 865 ASSERT_STREQ(L" muppet", p); 866 867 ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"+inf", nullptr)); 868 ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"inf", nullptr)); 869 ASSERT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-inf", nullptr)); 870 871 ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"+infinity", nullptr)); 872 ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"infinity", nullptr)); 873 ASSERT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-infinity", nullptr)); 874 875 ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"+infinitude", &p)); 876 ASSERT_STREQ(L"initude", p); 877 ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"infinitude", &p)); 878 ASSERT_STREQ(L"initude", p); 879 ASSERT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-infinitude", &p)); 880 ASSERT_STREQ(L"initude", p); 881 882 // Check case-insensitivity. 883 ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"InFiNiTy", nullptr)); 884 ASSERT_TRUE(isnan(fn(L"NaN", nullptr))); 885 } 886 TEST(wchar,wcstof)887 TEST(wchar, wcstof) { 888 TestWcsToFloat(wcstof); 889 } 890 TEST(wchar,wcstof_hex_floats)891 TEST(wchar, wcstof_hex_floats) { 892 TestWcsToFloatHexFloats(wcstof); 893 } 894 TEST(wchar,wcstof_hex_inf_nan)895 TEST(wchar, wcstof_hex_inf_nan) { 896 TestWcsToFloatInfNan(wcstof); 897 } 898 TEST(wchar,wcstod)899 TEST(wchar, wcstod) { 900 TestWcsToFloat(wcstod); 901 } 902 TEST(wchar,wcstod_hex_floats)903 TEST(wchar, wcstod_hex_floats) { 904 TestWcsToFloatHexFloats(wcstod); 905 } 906 TEST(wchar,wcstod_hex_inf_nan)907 TEST(wchar, wcstod_hex_inf_nan) { 908 TestWcsToFloatInfNan(wcstod); 909 } 910 TEST(wchar,wcstold)911 TEST(wchar, wcstold) { 912 TestWcsToFloat(wcstold); 913 } 914 TEST(wchar,wcstold_hex_floats)915 TEST(wchar, wcstold_hex_floats) { 916 TestWcsToFloatHexFloats(wcstold); 917 } 918 TEST(wchar,wcstold_hex_inf_nan)919 TEST(wchar, wcstold_hex_inf_nan) { 920 TestWcsToFloatInfNan(wcstold); 921 } 922 TEST(wchar,wcstod_l)923 TEST(wchar, wcstod_l) { 924 #if !defined(ANDROID_HOST_MUSL) 925 EXPECT_EQ(1.23, wcstod_l(L"1.23", nullptr, LC_GLOBAL_LOCALE)); 926 #else 927 GTEST_SKIP() << "musl doesn't have wcstod_l"; 928 #endif 929 } 930 TEST(wchar,wcstof_l)931 TEST(wchar, wcstof_l) { 932 #if !defined(ANDROID_HOST_MUSL) 933 EXPECT_EQ(1.23f, wcstof_l(L"1.23", nullptr, LC_GLOBAL_LOCALE)); 934 #else 935 GTEST_SKIP() << "musl doesn't have wcstof_l"; 936 #endif 937 } 938 TEST(wchar,wcstol_l)939 TEST(wchar, wcstol_l) { 940 #if !defined(ANDROID_HOST_MUSL) 941 EXPECT_EQ(123L, wcstol_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE)); 942 #else 943 GTEST_SKIP() << "musl doesn't have wcstol_l"; 944 #endif 945 } 946 TEST(wchar,wcstold_l)947 TEST(wchar, wcstold_l) { 948 EXPECT_EQ(1.23L, wcstold_l(L"1.23", nullptr, LC_GLOBAL_LOCALE)); 949 } 950 TEST(wchar,wcstoll_l)951 TEST(wchar, wcstoll_l) { 952 EXPECT_EQ(123LL, wcstoll_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE)); 953 } 954 TEST(wchar,wcstoul_l)955 TEST(wchar, wcstoul_l) { 956 #if !defined(ANDROID_HOST_MUSL) 957 EXPECT_EQ(123UL, wcstoul_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE)); 958 #else 959 GTEST_SKIP() << "musl doesn't have wcstoul_l"; 960 #endif 961 } 962 TEST(wchar,wcstoull_l)963 TEST(wchar, wcstoull_l) { 964 EXPECT_EQ(123ULL, wcstoull_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE)); 965 } 966 AssertWcwidthRange(wchar_t begin,wchar_t end,int expected)967 static void AssertWcwidthRange(wchar_t begin, wchar_t end, int expected) { 968 for (wchar_t i = begin; i < end; ++i) { 969 EXPECT_EQ(expected, wcwidth(i)) << static_cast<int>(i); 970 } 971 } 972 TEST(wchar,wcwidth_NUL)973 TEST(wchar, wcwidth_NUL) { 974 // NUL is defined to return 0 rather than -1, despite being a C0 control. 975 EXPECT_EQ(0, wcwidth(0)); 976 } 977 TEST(wchar,wcwidth_ascii)978 TEST(wchar, wcwidth_ascii) { 979 AssertWcwidthRange(0x20, 0x7f, 1); // Non-C0 non-DEL ASCII. 980 } 981 TEST(wchar,wcwidth_controls)982 TEST(wchar, wcwidth_controls) { 983 AssertWcwidthRange(0x01, 0x20, -1); // C0 controls. 984 EXPECT_EQ(-1, wcwidth(0x7f)); // DEL. 985 AssertWcwidthRange(0x80, 0xa0, -1); // C1 controls. 986 } 987 TEST(wchar,wcwidth_non_spacing_and_enclosing_marks_and_format)988 TEST(wchar, wcwidth_non_spacing_and_enclosing_marks_and_format) { 989 if (!have_dl()) return; 990 991 EXPECT_EQ(0, wcwidth(0x0300)); // Combining grave. 992 EXPECT_EQ(0, wcwidth(0x20dd)); // Combining enclosing circle. 993 EXPECT_EQ(0, wcwidth(0x00ad)); // Soft hyphen (SHY). 994 EXPECT_EQ(0, wcwidth(0x200b)); // Zero width space. 995 } 996 TEST(wchar,wcwidth_cjk)997 TEST(wchar, wcwidth_cjk) { 998 if (!have_dl()) return; 999 1000 EXPECT_EQ(2, wcwidth(0x4e00)); // Start of CJK unified block. 1001 EXPECT_EQ(2, wcwidth(0x9fff)); // End of CJK unified block. 1002 EXPECT_EQ(2, wcwidth(0x3400)); // Start of CJK extension A block. 1003 EXPECT_EQ(2, wcwidth(0x4dbf)); // End of CJK extension A block. 1004 EXPECT_EQ(2, wcwidth(0x20000)); // Start of CJK extension B block. 1005 EXPECT_EQ(2, wcwidth(0x2a6df)); // End of CJK extension B block. 1006 } 1007 TEST(wchar,wcwidth_korean_combining_jamo)1008 TEST(wchar, wcwidth_korean_combining_jamo) { 1009 if (!have_dl()) return; 1010 1011 AssertWcwidthRange(0x1160, 0x1200, 0); // Original range. 1012 EXPECT_EQ(0, wcwidth(0xd7b0)); // Newer. 1013 EXPECT_EQ(0, wcwidth(0xd7cb)); 1014 } 1015 TEST(wchar,wcwidth_korean_jeongeul_syllables)1016 TEST(wchar, wcwidth_korean_jeongeul_syllables) { 1017 if (!have_dl()) return; 1018 1019 EXPECT_EQ(2, wcwidth(0xac00)); // Start of block. 1020 EXPECT_EQ(2, wcwidth(0xd7a3)); // End of defined code points in Unicode 7. 1021 // Undefined characters at the end of the block have width 1. 1022 } 1023 TEST(wchar,wcwidth_kana)1024 TEST(wchar, wcwidth_kana) { 1025 if (!have_dl()) return; 1026 1027 // Hiragana (most, not undefined). 1028 AssertWcwidthRange(0x3041, 0x3097, 2); 1029 // Katakana. 1030 AssertWcwidthRange(0x30a0, 0x3100, 2); 1031 } 1032 TEST(wchar,wcwidth_circled_two_digit_cjk)1033 TEST(wchar, wcwidth_circled_two_digit_cjk) { 1034 if (!have_dl()) return; 1035 1036 // Circled two-digit CJK "speed sign" numbers are wide, 1037 // though EastAsianWidth is ambiguous. 1038 AssertWcwidthRange(0x3248, 0x3250, 2); 1039 } 1040 TEST(wchar,wcwidth_hexagrams)1041 TEST(wchar, wcwidth_hexagrams) { 1042 if (!have_dl()) return; 1043 1044 // Hexagrams are wide, though EastAsianWidth is neutral. 1045 AssertWcwidthRange(0x4dc0, 0x4e00, 2); 1046 } 1047 TEST(wchar,wcwidth_default_ignorables)1048 TEST(wchar, wcwidth_default_ignorables) { 1049 if (!have_dl()) return; 1050 1051 AssertWcwidthRange(0xfff0, 0xfff8, 0); // Unassigned by default ignorable. 1052 EXPECT_EQ(0, wcwidth(0xe0000)); // ...through 0xe0fff. 1053 } 1054 TEST(wchar,wcwidth_korean_common_non_syllables)1055 TEST(wchar, wcwidth_korean_common_non_syllables) { 1056 if (!have_dl()) return; 1057 1058 EXPECT_EQ(2, wcwidth(L'ㅜ')); // Korean "crying" emoticon. 1059 EXPECT_EQ(2, wcwidth(L'ㅋ')); // Korean "laughing" emoticon. 1060 } 1061 TEST(wchar,wcswidth)1062 TEST(wchar, wcswidth) { 1063 EXPECT_EQ(2, wcswidth(L"abc", 2)); 1064 EXPECT_EQ(2, wcswidth(L"ab\t", 2)); 1065 EXPECT_EQ(-1, wcswidth(L"a\tb", 2)); 1066 } 1067 TEST(wchar,wcslcpy)1068 TEST(wchar, wcslcpy) { 1069 #if defined(__BIONIC__) 1070 wchar_t dst[32]; 1071 ASSERT_EQ(11U, wcslcpy(dst, L"hello world", 3)); 1072 ASSERT_STREQ(L"he", dst); 1073 ASSERT_EQ(11U, wcslcpy(dst, L"hello world", 32)); 1074 ASSERT_STREQ(L"hello world", dst); 1075 #else 1076 GTEST_SKIP() << "no wcslcpy in glibc"; 1077 #endif 1078 } 1079 TEST(wchar,wcscat)1080 TEST(wchar, wcscat) { 1081 wchar_t dst[32]; 1082 ASSERT_EQ(dst, wcscat(dst, L"hello")); 1083 ASSERT_STREQ(dst, L"hello"); 1084 ASSERT_EQ(dst, wcscat(dst, L" world")); 1085 ASSERT_STREQ(dst, L"hello world"); 1086 } 1087 TEST(wchar,wcscpy)1088 TEST(wchar, wcscpy) { 1089 wchar_t dst[32]; 1090 ASSERT_EQ(dst, wcscpy(dst, L"hello")); 1091 ASSERT_STREQ(dst, L"hello"); 1092 ASSERT_EQ(dst, wcscpy(dst, L"world")); 1093 ASSERT_STREQ(dst, L"world"); 1094 } 1095 TEST(wchar,wcscasecmp)1096 TEST(wchar, wcscasecmp) { 1097 ASSERT_EQ(0, wcscasecmp(L"hello", L"HELLO")); 1098 ASSERT_TRUE(wcscasecmp(L"hello1", L"HELLO2") < 0); 1099 ASSERT_TRUE(wcscasecmp(L"hello2", L"HELLO1") > 0); 1100 ASSERT_TRUE(wcscasecmp(L"hello", L"HELL") > 0); 1101 ASSERT_TRUE(wcscasecmp(L"hell", L"HELLO") < 0); 1102 } 1103 TEST(wchar,wcscspn)1104 TEST(wchar, wcscspn) { 1105 ASSERT_EQ(0U, wcscspn(L"hello world", L"abcdefghijklmnopqrstuvwxyz")); 1106 ASSERT_EQ(5U, wcscspn(L"hello world", L" ")); 1107 ASSERT_EQ(11U, wcscspn(L"hello world", L"!")); 1108 } 1109 TEST(wchar,wcsspn)1110 TEST(wchar, wcsspn) { 1111 ASSERT_EQ(0U, wcsspn(L"hello world", L"!")); 1112 ASSERT_EQ(5U, wcsspn(L"hello world", L"abcdefghijklmnopqrstuvwxyz")); 1113 ASSERT_EQ(11U, wcsspn(L"hello world", L"abcdefghijklmnopqrstuvwxyz ")); 1114 } 1115 TEST(wchar,wcsdup)1116 TEST(wchar, wcsdup) { 1117 wchar_t* s = wcsdup(L"hello"); 1118 ASSERT_STREQ(s, L"hello"); 1119 free(s); 1120 } 1121 TEST(wchar,wcslcat)1122 TEST(wchar, wcslcat) { 1123 #if defined(__BIONIC__) 1124 wchar_t dst[4] = {}; 1125 ASSERT_EQ(1U, wcslcat(dst, L"a", 4)); 1126 ASSERT_EQ(7U, wcslcat(dst, L"bcdefg", 4)); 1127 ASSERT_STREQ(dst, L"abc"); 1128 #else 1129 GTEST_SKIP() << "no wcslcpy in glibc"; 1130 #endif 1131 } 1132 TEST(wchar,wcsncasecmp)1133 TEST(wchar, wcsncasecmp) { 1134 ASSERT_EQ(0, wcsncasecmp(L"foo", L"bar", 0)); 1135 1136 ASSERT_EQ(0, wcsncasecmp(L"hello1", L"HELLO2", 5)); 1137 ASSERT_TRUE(wcsncasecmp(L"hello1", L"HELLO2", 6) < 0); 1138 ASSERT_TRUE(wcsncasecmp(L"hello2", L"HELLO1", 6) > 0); 1139 ASSERT_TRUE(wcsncasecmp(L"hello", L"HELL", 5) > 0); 1140 ASSERT_TRUE(wcsncasecmp(L"hell", L"HELLO", 5) < 0); 1141 } 1142 TEST(wchar,wcsncat)1143 TEST(wchar, wcsncat) { 1144 wchar_t dst[32]; 1145 ASSERT_EQ(dst, wcsncat(dst, L"hello, world!", 5)); 1146 ASSERT_STREQ(dst, L"hello"); 1147 ASSERT_EQ(dst, wcsncat(dst, L"hello, world!", 0)); 1148 ASSERT_STREQ(dst, L"hello"); 1149 ASSERT_EQ(dst, wcsncat(dst, L", world!", 8)); 1150 ASSERT_STREQ(dst, L"hello, world!"); 1151 } 1152 TEST(wchar,wcsncmp)1153 TEST(wchar, wcsncmp) { 1154 ASSERT_EQ(0, wcsncmp(L"foo", L"bar", 0)); 1155 ASSERT_EQ(0, wcsncmp(L"aaaa", L"aaab", 3)); 1156 ASSERT_TRUE(wcsncmp(L"aaaa", L"aaab", 4) < 0); 1157 ASSERT_TRUE(wcsncmp(L"aaab", L"aaaa", 4) > 0); 1158 } 1159 TEST(wchar,wcsnlen)1160 TEST(wchar, wcsnlen) { 1161 ASSERT_EQ(2U, wcsnlen(L"hello", 2)); 1162 ASSERT_EQ(5U, wcsnlen(L"hello", 5)); 1163 ASSERT_EQ(5U, wcsnlen(L"hello", 666)); 1164 } 1165 TEST(wchar,wcspbrk)1166 TEST(wchar, wcspbrk) { 1167 const wchar_t* s = L"hello, world!"; 1168 ASSERT_EQ(nullptr, wcspbrk(s, L"-")); 1169 ASSERT_EQ(s, wcspbrk(s, L"abch")); 1170 ASSERT_EQ(s + 2, wcspbrk(s, L"l")); 1171 ASSERT_EQ(s + 5, wcspbrk(s, L",. !")); 1172 } 1173 TEST(wchar,wcstok)1174 TEST(wchar, wcstok) { 1175 wchar_t s[] = L"this is\ta\nstring"; 1176 wchar_t* p; 1177 ASSERT_EQ(s, wcstok(s, L"\t\n ", &p)); 1178 ASSERT_STREQ(s, L"this"); 1179 ASSERT_STREQ(p, L"is\ta\nstring"); 1180 ASSERT_EQ(s + 5, wcstok(nullptr, L"\t\n ", &p)); 1181 ASSERT_STREQ(s + 5, L"is"); 1182 ASSERT_STREQ(p, L"a\nstring"); 1183 ASSERT_EQ(s + 8, wcstok(nullptr, L"\t\n ", &p)); 1184 ASSERT_STREQ(s + 8, L"a"); 1185 ASSERT_STREQ(p, L"string"); 1186 ASSERT_EQ(s + 10, wcstok(nullptr, L"\t\n ", &p)); 1187 ASSERT_STREQ(s + 10, L"string"); 1188 ASSERT_EQ(nullptr, p); 1189 } 1190 TEST(wchar,wmemchr)1191 TEST(wchar, wmemchr) { 1192 const wchar_t* s = L"hello, world!"; 1193 ASSERT_EQ(s, wmemchr(s, L'h', 13)); 1194 ASSERT_EQ(s + 5, wmemchr(s, L',', 13)); 1195 ASSERT_EQ(s + 12, wmemchr(s, L'!', 13)); 1196 ASSERT_EQ(nullptr, wmemchr(s, L'a', 13)); 1197 } 1198 TEST(wchar,wmemcmp)1199 TEST(wchar, wmemcmp) { 1200 ASSERT_EQ(0, wmemcmp(L"aaaa", L"aaab", 3)); 1201 ASSERT_TRUE(wmemcmp(L"aaaa", L"aaab", 4) < 0); 1202 ASSERT_TRUE(wmemcmp(L"aaab", L"aaaa", 4) > 0); 1203 } 1204 TEST(wchar,wmemcpy)1205 TEST(wchar, wmemcpy) { 1206 wchar_t dst[32] = {}; 1207 ASSERT_EQ(dst, wmemcpy(dst, L"hello", 5)); 1208 ASSERT_STREQ(dst, L"hello"); 1209 } 1210 TEST(wchar,wmemmove)1211 TEST(wchar, wmemmove) { 1212 wchar_t dst[32] = {}; 1213 ASSERT_EQ(dst, wmemmove(dst, L"hello", 5)); 1214 ASSERT_STREQ(dst, L"hello"); 1215 } 1216 TEST(wchar,wmemset)1217 TEST(wchar, wmemset) { 1218 wchar_t dst[4] = {}; 1219 ASSERT_EQ(dst, wmemset(dst, 0x12345678, 3)); 1220 ASSERT_EQ(dst[0], wchar_t(0x12345678)); 1221 ASSERT_EQ(dst[1], wchar_t(0x12345678)); 1222 ASSERT_EQ(dst[2], wchar_t(0x12345678)); 1223 ASSERT_EQ(dst[3], wchar_t(0)); 1224 ASSERT_EQ(dst, wmemset(dst, L'y', 0)); 1225 ASSERT_EQ(dst[0], wchar_t(0x12345678)); 1226 } 1227