string_test.cpp revision e5bbb6b6ab662503f06ceb20fa841d2e558d596d
1/* 2 * Copyright (C) 2012 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 <math.h> 21#include <string.h> 22 23#include "buffer_tests.h" 24 25#define KB 1024 26#define SMALL 1*KB 27#define MEDIUM 4*KB 28#define LARGE 64*KB 29 30static int signum(int i) { 31 if (i < 0) { 32 return -1; 33 } else if (i > 0) { 34 return 1; 35 } 36 return 0; 37} 38 39TEST(string, strerror) { 40 // Valid. 41 ASSERT_STREQ("Success", strerror(0)); 42 ASSERT_STREQ("Operation not permitted", strerror(1)); 43 44 // Invalid. 45 ASSERT_STREQ("Unknown error -1", strerror(-1)); 46 ASSERT_STREQ("Unknown error 1234", strerror(1234)); 47} 48 49#if __BIONIC__ // glibc's strerror isn't thread safe, only its strsignal. 50 51static void* ConcurrentStrErrorFn(void*) { 52 bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0); 53 return reinterpret_cast<void*>(equal); 54} 55 56TEST(string, strerror_concurrent) { 57 const char* strerror1001 = strerror(1001); 58 ASSERT_STREQ("Unknown error 1001", strerror1001); 59 60 pthread_t t; 61 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL)); 62 void* result; 63 ASSERT_EQ(0, pthread_join(t, &result)); 64 ASSERT_TRUE(static_cast<bool>(result)); 65 66 ASSERT_STREQ("Unknown error 1001", strerror1001); 67} 68 69#endif 70 71#if __BIONIC__ // glibc's strerror_r doesn't even have the same signature as the POSIX one. 72TEST(string, strerror_r) { 73 char buf[256]; 74 75 // Valid. 76 ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf))); 77 ASSERT_STREQ("Success", buf); 78 ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf))); 79 ASSERT_STREQ("Operation not permitted", buf); 80 81 // Invalid. 82 ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf))); 83 ASSERT_STREQ("Unknown error -1", buf); 84 ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf))); 85 ASSERT_STREQ("Unknown error 1234", buf); 86 87 // Buffer too small. 88 ASSERT_EQ(-1, strerror_r(0, buf, 2)); 89 ASSERT_EQ(ERANGE, errno); 90} 91#endif 92 93TEST(string, strsignal) { 94 // A regular signal. 95 ASSERT_STREQ("Hangup", strsignal(1)); 96 97 // A real-time signal. 98#ifdef __GLIBC__ // glibc reserves real-time signals for internal use, and doesn't count those. 99 ASSERT_STREQ("Real-time signal 14", strsignal(48)); 100#else 101 ASSERT_STREQ("Real-time signal 16", strsignal(48)); 102#endif 103 104 // Errors. 105 ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small. 106 ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small. 107 ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large. 108} 109 110static void* ConcurrentStrSignalFn(void*) { 111 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0); 112 return reinterpret_cast<void*>(equal); 113} 114 115TEST(string, strsignal_concurrent) { 116 const char* strsignal1001 = strsignal(1001); 117 ASSERT_STREQ("Unknown signal 1001", strsignal1001); 118 119 pthread_t t; 120 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL)); 121 void* result; 122 ASSERT_EQ(0, pthread_join(t, &result)); 123 ASSERT_TRUE(static_cast<bool>(result)); 124 125 ASSERT_STREQ("Unknown signal 1001", strsignal1001); 126} 127 128// TODO: where did these numbers come from? 129#define POS_ITER 10 130#define ITER 500 131 132// For every length we want to test, vary and change alignment 133// of allocated memory, fill it with some values, calculate 134// expected result and then run function and compare what we got. 135// These tests contributed by Intel Corporation. 136// TODO: make these tests more intention-revealing and less random. 137template<class Character> 138struct StringTestState { 139 StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) { 140 int max_alignment = 64; 141 142 // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN". 143 glob_ptr = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment)); 144 glob_ptr1 = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment)); 145 glob_ptr2 = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment)); 146 147 InitLenArray(); 148 149 srandom(1234); 150 } 151 152 ~StringTestState() { 153 free(glob_ptr); 154 free(glob_ptr1); 155 free(glob_ptr2); 156 } 157 158 void NewIteration() { 159 int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 }; 160 int usable_alignments = 10; 161 int align1 = alignments[random() % (usable_alignments - 1)]; 162 int align2 = alignments[random() % (usable_alignments - 1)]; 163 164 ptr = glob_ptr + align1; 165 ptr1 = glob_ptr1 + align1; 166 ptr2 = glob_ptr2 + align2; 167 } 168 169 const size_t MAX_LEN; 170 Character *ptr, *ptr1, *ptr2; 171 size_t n; 172 int len[ITER + 1]; 173 174 private: 175 Character *glob_ptr, *glob_ptr1, *glob_ptr2; 176 177 // Calculate input lengths and fill state.len with them. 178 // Test small lengths with more density than big ones. Manually push 179 // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats. 180 // Return number of lengths to test. 181 void InitLenArray() { 182 n = 0; 183 len[n++] = 0; 184 for (size_t i = 1; i < ITER; ++i) { 185 int l = (int) exp(log((double) MAX_LEN) * i / ITER); 186 if (l != len[n - 1]) { 187 len[n++] = l; 188 } 189 } 190 len[n++] = MAX_LEN; 191 } 192}; 193 194TEST(string, strcat) { 195 StringTestState<char> state(SMALL); 196 for (size_t i = 1; i < state.n; i++) { 197 for (size_t j = 0; j < POS_ITER; j++) { 198 state.NewIteration(); 199 200 memset(state.ptr2, '\2', state.MAX_LEN); 201 state.ptr2[state.MAX_LEN - 1] = '\0'; 202 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN); 203 204 memset(state.ptr1, random() & 255, state.len[i]); 205 state.ptr1[random() % state.len[i]] = '\0'; 206 state.ptr1[state.len[i] - 1] = '\0'; 207 208 strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1); 209 210 EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2); 211 EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0); 212 } 213 } 214} 215 216// one byte target with "\0" source 217TEST(string, strcpy2) { 218 char buf[1]; 219 char* orig = strdup(""); 220 strcpy(buf, orig); 221 ASSERT_EQ('\0', buf[0]); 222 free(orig); 223} 224 225// multibyte target where we under fill target 226TEST(string, strcpy3) { 227 char buf[10]; 228 char* orig = strdup("12345"); 229 memset(buf, 'A', sizeof(buf)); 230 strcpy(buf, orig); 231 ASSERT_EQ('1', buf[0]); 232 ASSERT_EQ('2', buf[1]); 233 ASSERT_EQ('3', buf[2]); 234 ASSERT_EQ('4', buf[3]); 235 ASSERT_EQ('5', buf[4]); 236 ASSERT_EQ('\0', buf[5]); 237 ASSERT_EQ('A', buf[6]); 238 ASSERT_EQ('A', buf[7]); 239 ASSERT_EQ('A', buf[8]); 240 ASSERT_EQ('A', buf[9]); 241 free(orig); 242} 243 244// multibyte target where we fill target exactly 245TEST(string, strcpy4) { 246 char buf[10]; 247 char* orig = strdup("123456789"); 248 memset(buf, 'A', sizeof(buf)); 249 strcpy(buf, orig); 250 ASSERT_EQ('1', buf[0]); 251 ASSERT_EQ('2', buf[1]); 252 ASSERT_EQ('3', buf[2]); 253 ASSERT_EQ('4', buf[3]); 254 ASSERT_EQ('5', buf[4]); 255 ASSERT_EQ('6', buf[5]); 256 ASSERT_EQ('7', buf[6]); 257 ASSERT_EQ('8', buf[7]); 258 ASSERT_EQ('9', buf[8]); 259 ASSERT_EQ('\0', buf[9]); 260 free(orig); 261} 262 263TEST(string, strcat2) { 264 char buf[10]; 265 memset(buf, 'A', sizeof(buf)); 266 buf[0] = 'a'; 267 buf[1] = '\0'; 268 char* res = strcat(buf, "01234"); 269 ASSERT_EQ(buf, res); 270 ASSERT_EQ('a', buf[0]); 271 ASSERT_EQ('0', buf[1]); 272 ASSERT_EQ('1', buf[2]); 273 ASSERT_EQ('2', buf[3]); 274 ASSERT_EQ('3', buf[4]); 275 ASSERT_EQ('4', buf[5]); 276 ASSERT_EQ('\0', buf[6]); 277 ASSERT_EQ('A', buf[7]); 278 ASSERT_EQ('A', buf[8]); 279 ASSERT_EQ('A', buf[9]); 280} 281 282TEST(string, strcat3) { 283 char buf[10]; 284 memset(buf, 'A', sizeof(buf)); 285 buf[0] = 'a'; 286 buf[1] = '\0'; 287 char* res = strcat(buf, "01234567"); 288 ASSERT_EQ(buf, res); 289 ASSERT_EQ('a', buf[0]); 290 ASSERT_EQ('0', buf[1]); 291 ASSERT_EQ('1', buf[2]); 292 ASSERT_EQ('2', buf[3]); 293 ASSERT_EQ('3', buf[4]); 294 ASSERT_EQ('4', buf[5]); 295 ASSERT_EQ('5', buf[6]); 296 ASSERT_EQ('6', buf[7]); 297 ASSERT_EQ('7', buf[8]); 298 ASSERT_EQ('\0', buf[9]); 299} 300 301TEST(string, strncat2) { 302 char buf[10]; 303 memset(buf, 'A', sizeof(buf)); 304 buf[0] = 'a'; 305 buf[1] = '\0'; 306 char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1); 307 ASSERT_EQ(buf, res); 308 ASSERT_EQ('a', buf[0]); 309 ASSERT_EQ('0', buf[1]); 310 ASSERT_EQ('1', buf[2]); 311 ASSERT_EQ('2', buf[3]); 312 ASSERT_EQ('3', buf[4]); 313 ASSERT_EQ('4', buf[5]); 314 ASSERT_EQ('\0', buf[6]); 315 ASSERT_EQ('A', buf[7]); 316 ASSERT_EQ('A', buf[8]); 317 ASSERT_EQ('A', buf[9]); 318} 319 320TEST(string, strncat3) { 321 char buf[10]; 322 memset(buf, 'A', sizeof(buf)); 323 buf[0] = 'a'; 324 buf[1] = '\0'; 325 char* res = strncat(buf, "0123456789", 5); 326 ASSERT_EQ(buf, res); 327 ASSERT_EQ('a', buf[0]); 328 ASSERT_EQ('0', buf[1]); 329 ASSERT_EQ('1', buf[2]); 330 ASSERT_EQ('2', buf[3]); 331 ASSERT_EQ('3', buf[4]); 332 ASSERT_EQ('4', buf[5]); 333 ASSERT_EQ('\0', buf[6]); 334 ASSERT_EQ('A', buf[7]); 335 ASSERT_EQ('A', buf[8]); 336 ASSERT_EQ('A', buf[9]); 337} 338 339TEST(string, strncat4) { 340 char buf[10]; 341 memset(buf, 'A', sizeof(buf)); 342 buf[0] = 'a'; 343 buf[1] = '\0'; 344 char* res = strncat(buf, "01234567", 8); 345 ASSERT_EQ(buf, res); 346 ASSERT_EQ('a', buf[0]); 347 ASSERT_EQ('0', buf[1]); 348 ASSERT_EQ('1', buf[2]); 349 ASSERT_EQ('2', buf[3]); 350 ASSERT_EQ('3', buf[4]); 351 ASSERT_EQ('4', buf[5]); 352 ASSERT_EQ('5', buf[6]); 353 ASSERT_EQ('6', buf[7]); 354 ASSERT_EQ('7', buf[8]); 355 ASSERT_EQ('\0', buf[9]); 356} 357 358TEST(string, strncat5) { 359 char buf[10]; 360 memset(buf, 'A', sizeof(buf)); 361 buf[0] = 'a'; 362 buf[1] = '\0'; 363 char* res = strncat(buf, "01234567", 9); 364 ASSERT_EQ(buf, res); 365 ASSERT_EQ('a', buf[0]); 366 ASSERT_EQ('0', buf[1]); 367 ASSERT_EQ('1', buf[2]); 368 ASSERT_EQ('2', buf[3]); 369 ASSERT_EQ('3', buf[4]); 370 ASSERT_EQ('4', buf[5]); 371 ASSERT_EQ('5', buf[6]); 372 ASSERT_EQ('6', buf[7]); 373 ASSERT_EQ('7', buf[8]); 374 ASSERT_EQ('\0', buf[9]); 375} 376 377TEST(string, strchr_with_0) { 378 char buf[10]; 379 const char* s = "01234"; 380 memcpy(buf, s, strlen(s) + 1); 381 EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s))); 382} 383 384TEST(string, strchr) { 385 int seek_char = random() & 255; 386 387 StringTestState<char> state(SMALL); 388 for (size_t i = 1; i < state.n; i++) { 389 for (size_t j = 0; j < POS_ITER; j++) { 390 state.NewIteration(); 391 392 if (~seek_char > 0) { 393 memset(state.ptr1, ~seek_char, state.len[i]); 394 } else { 395 memset(state.ptr1, '\1', state.len[i]); 396 } 397 state.ptr1[state.len[i] - 1] = '\0'; 398 399 int pos = random() % state.MAX_LEN; 400 char* expected; 401 if (pos >= state.len[i] - 1) { 402 if (seek_char == 0) { 403 expected = state.ptr1 + state.len[i] - 1; 404 } else { 405 expected = NULL; 406 } 407 } else { 408 state.ptr1[pos] = seek_char; 409 expected = state.ptr1 + pos; 410 } 411 412 ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected); 413 } 414 } 415} 416 417TEST(string, strcmp) { 418 StringTestState<char> state(SMALL); 419 for (size_t i = 1; i < state.n; i++) { 420 for (size_t j = 0; j < POS_ITER; j++) { 421 state.NewIteration(); 422 423 memset(state.ptr1, 'v', state.MAX_LEN); 424 memset(state.ptr2, 'n', state.MAX_LEN); 425 state.ptr1[state.len[i] - 1] = '\0'; 426 state.ptr2[state.len[i] - 1] = '\0'; 427 428 int pos = 1 + (random() % (state.MAX_LEN - 1)); 429 int actual; 430 int expected; 431 if (pos >= state.len[i] - 1) { 432 memcpy(state.ptr1, state.ptr2, state.len[i]); 433 expected = 0; 434 actual = strcmp(state.ptr1, state.ptr2); 435 } else { 436 memcpy(state.ptr1, state.ptr2, pos); 437 if (state.ptr1[pos] > state.ptr2[pos]) { 438 expected = 1; 439 } else if (state.ptr1[pos] == state.ptr2[pos]) { 440 state.ptr1[pos + 1] = '\0'; 441 state.ptr2[pos + 1] = '\0'; 442 expected = 0; 443 } else { 444 expected = -1; 445 } 446 actual = strcmp(state.ptr1, state.ptr2); 447 } 448 449 ASSERT_EQ(expected, signum(actual)); 450 } 451 } 452} 453 454TEST(string, strcpy) { 455 StringTestState<char> state(SMALL); 456 for (size_t j = 0; j < POS_ITER; j++) { 457 state.NewIteration(); 458 459 size_t pos = random() % state.MAX_LEN; 460 461 memset(state.ptr1, '\2', pos); 462 state.ptr1[pos] = '\0'; 463 state.ptr1[state.MAX_LEN - 1] = '\0'; 464 465 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 466 467 memset(state.ptr2, '\1', state.MAX_LEN); 468 state.ptr2[state.MAX_LEN - 1] = '\0'; 469 470 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN); 471 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 472 state.ptr[2 * state.MAX_LEN - 1] = '\0'; 473 474 ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2); 475 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 || 476 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0)); 477 } 478} 479 480 481#if __BIONIC__ 482TEST(string, strlcat) { 483 StringTestState<char> state(SMALL); 484 for (size_t i = 0; i < state.n; i++) { 485 for (size_t j = 0; j < POS_ITER; j++) { 486 state.NewIteration(); 487 488 memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]); 489 state.ptr2[state.MAX_LEN - 1] = '\0'; 490 memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]); 491 492 int pos = random() % state.MAX_LEN; 493 memset(state.ptr1, '\3', pos); 494 state.ptr1[pos] = '\0'; 495 if (pos < state.len[i]) { 496 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1); 497 } else { 498 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]); 499 state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0'; 500 } 501 502 strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]); 503 504 ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0); 505 } 506 } 507} 508#endif 509 510#if __BIONIC__ 511TEST(string, strlcpy) { 512 StringTestState<char> state(SMALL); 513 for (size_t j = 0; j < POS_ITER; j++) { 514 state.NewIteration(); 515 516 int rand = random() & 255; 517 if (rand < 1) { 518 rand = 1; 519 } 520 memset(state.ptr1, rand, state.MAX_LEN); 521 522 size_t pos = random() % state.MAX_LEN; 523 if (pos < state.MAX_LEN) { 524 state.ptr1[pos] = '\0'; 525 } 526 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 527 528 memset(state.ptr2, random() & 255, state.MAX_LEN); 529 memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN); 530 531 if (pos > state.MAX_LEN - 1) { 532 memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN); 533 state.ptr[2 * state.MAX_LEN - 1] = '\0'; 534 } else { 535 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 536 } 537 538 ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1)); 539 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) || 540 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0)); 541 } 542} 543#endif 544 545TEST(string, strncat) { 546 StringTestState<char> state(SMALL); 547 for (size_t i = 1; i < state.n; i++) { 548 for (size_t j = 0; j < POS_ITER; j++) { 549 state.NewIteration(); 550 551 memset(state.ptr2, '\2', state.MAX_LEN); 552 state.ptr2[state.MAX_LEN - 1] = '\0'; 553 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN); 554 555 memset(state.ptr1, random() & 255, state.len[i]); 556 state.ptr1[random() % state.len[i]] = '\0'; 557 state.ptr1[state.len[i] - 1] = '\0'; 558 559 size_t pos = strlen(state.ptr1); 560 561 size_t actual = random() % state.len[i]; 562 strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos)); 563 state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0'; 564 565 ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2); 566 ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0); 567 } 568 } 569} 570 571TEST(string, strncmp) { 572 StringTestState<char> state(SMALL); 573 for (size_t i = 1; i < state.n; i++) { 574 for (size_t j = 0; j < POS_ITER; j++) { 575 state.NewIteration(); 576 577 memset(state.ptr1, 'v', state.MAX_LEN); 578 memset(state.ptr2, 'n', state.MAX_LEN); 579 state.ptr1[state.len[i] - 1] = '\0'; 580 state.ptr2[state.len[i] - 1] = '\0'; 581 582 int pos = 1 + (random() % (state.MAX_LEN - 1)); 583 int actual; 584 int expected; 585 if (pos >= state.len[i] - 1) { 586 memcpy(state.ptr1, state.ptr2, state.len[i]); 587 expected = 0; 588 actual = strncmp(state.ptr1, state.ptr2, state.len[i]); 589 } else { 590 memcpy(state.ptr1, state.ptr2, pos); 591 if (state.ptr1[pos] > state.ptr2[pos]) { 592 expected = 1; 593 } else if (state.ptr1[pos] == state.ptr2[pos]) { 594 state.ptr1[pos + 1] = '\0'; 595 state.ptr2[pos + 1] = '\0'; 596 expected = 0; 597 } else { 598 expected = -1; 599 } 600 actual = strncmp(state.ptr1, state.ptr2, state.len[i]); 601 } 602 603 ASSERT_EQ(expected, signum(actual)); 604 } 605 } 606} 607 608TEST(string, strncpy) { 609 StringTestState<char> state(SMALL); 610 for (size_t j = 0; j < ITER; j++) { 611 state.NewIteration(); 612 613 memset(state.ptr1, random() & 255, state.MAX_LEN); 614 state.ptr1[random () % state.MAX_LEN] = '\0'; 615 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 616 617 memset(state.ptr2, '\1', state.MAX_LEN); 618 619 size_t pos; 620 if (memchr(state.ptr1, 0, state.MAX_LEN)) { 621 pos = strlen(state.ptr1); 622 } else { 623 pos = state.MAX_LEN - 1; 624 } 625 626 memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN); 627 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 628 629 ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2); 630 ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 || 631 memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0); 632 } 633} 634 635TEST(string, strrchr) { 636 int seek_char = random() & 255; 637 StringTestState<char> state(SMALL); 638 for (size_t i = 1; i < state.n; i++) { 639 for (size_t j = 0; j < POS_ITER; j++) { 640 state.NewIteration(); 641 642 if (~seek_char > 0) { 643 memset(state.ptr1, ~seek_char, state.len[i]); 644 } else { 645 memset(state.ptr1, '\1', state.len[i]); 646 } 647 state.ptr1[state.len[i] - 1] = '\0'; 648 649 int pos = random() % state.MAX_LEN; 650 char* expected; 651 if (pos >= state.len[i] - 1) { 652 if (seek_char == 0) { 653 expected = state.ptr1 + state.len[i] - 1; 654 } else { 655 expected = NULL; 656 } 657 } else { 658 state.ptr1[pos] = seek_char; 659 expected = state.ptr1 + pos; 660 } 661 662 ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected); 663 } 664 } 665} 666 667TEST(string, memchr) { 668 int seek_char = random() & 255; 669 StringTestState<char> state(SMALL); 670 for (size_t i = 0; i < state.n; i++) { 671 for (size_t j = 0; j < POS_ITER; j++) { 672 state.NewIteration(); 673 674 memset(state.ptr1, ~seek_char, state.len[i]); 675 676 int pos = random() % state.MAX_LEN; 677 char* expected; 678 if (pos >= state.len[i]) { 679 expected = NULL; 680 } else { 681 state.ptr1[pos] = seek_char; 682 expected = state.ptr1 + pos; 683 } 684 685 ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected); 686 } 687 } 688} 689 690TEST(string, memrchr) { 691 int seek_char = random() & 255; 692 StringTestState<char> state(SMALL); 693 for (size_t i = 0; i < state.n; i++) { 694 for (size_t j = 0; j < POS_ITER; j++) { 695 state.NewIteration(); 696 697 memset(state.ptr1, ~seek_char, state.len[i]); 698 699 int pos = random() % state.MAX_LEN; 700 char* expected; 701 if (pos >= state.len[i]) { 702 expected = NULL; 703 } else { 704 state.ptr1[pos] = seek_char; 705 expected = state.ptr1 + pos; 706 } 707 708 ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected); 709 } 710 } 711} 712 713TEST(string, memcmp) { 714 StringTestState<char> state(SMALL); 715 for (size_t i = 0; i < state.n; i++) { 716 for (size_t j = 0; j < POS_ITER; j++) { 717 state.NewIteration(); 718 719 int c1 = random() & 0xff; 720 int c2 = random() & 0xff; 721 memset(state.ptr1, c1, state.MAX_LEN); 722 memset(state.ptr2, c1, state.MAX_LEN); 723 724 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]); 725 state.ptr2[pos] = c2; 726 727 int expected = (static_cast<int>(c1) - static_cast<int>(c2)); 728 int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN); 729 730 ASSERT_EQ(signum(expected), signum(actual)); 731 } 732 } 733} 734 735#if defined(__BIONIC__) 736extern "C" int __memcmp16(const unsigned short *ptr1, const unsigned short *ptr2, size_t n); 737 738TEST(string, __memcmp16) { 739 StringTestState<unsigned short> state(SMALL); 740 741 for (size_t i = 0; i < state.n; i++) { 742 for (size_t j = 0; j < POS_ITER; j++) { 743 state.NewIteration(); 744 745 unsigned short mask = 0xffff; 746 unsigned short c1 = rand() & mask; 747 unsigned short c2 = rand() & mask; 748 749 std::fill(state.ptr1, state.ptr1 + state.MAX_LEN, c1); 750 std::fill(state.ptr2, state.ptr2 + state.MAX_LEN, c1); 751 752 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]); 753 state.ptr2[pos] = c2; 754 755 int expected = (static_cast<unsigned short>(c1) - static_cast<unsigned short>(c2)); 756 int actual = __memcmp16(state.ptr1, state.ptr2, (size_t) state.MAX_LEN); 757 758 ASSERT_EQ(expected, actual); 759 } 760 } 761} 762#endif 763 764TEST(string, wmemcmp) { 765 StringTestState<wchar_t> state(SMALL); 766 767 for (size_t i = 0; i < state.n; i++) { 768 for (size_t j = 0; j < POS_ITER; j++) { 769 state.NewIteration(); 770 771 long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1; 772 int c1 = rand() & mask; 773 int c2 = rand() & mask; 774 wmemset(state.ptr1, c1, state.MAX_LEN); 775 wmemset(state.ptr2, c1, state.MAX_LEN); 776 777 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]); 778 state.ptr2[pos] = c2; 779 780 int expected = (static_cast<int>(c1) - static_cast<int>(c2)); 781 int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN); 782 783 ASSERT_EQ(signum(expected), signum(actual)); 784 } 785 } 786} 787 788TEST(string, memcpy) { 789 StringTestState<char> state(LARGE); 790 int rand = random() & 255; 791 for (size_t i = 0; i < state.n - 1; i++) { 792 for (size_t j = 0; j < POS_ITER; j++) { 793 state.NewIteration(); 794 795 size_t pos = random() % (state.MAX_LEN - state.len[i]); 796 797 memset(state.ptr1, rand, state.len[i]); 798 memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 799 800 memset(state.ptr2, rand, state.len[i]); 801 memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 802 memset(state.ptr2 + pos, '\0', state.len[i]); 803 804 ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos); 805 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 806 } 807 } 808} 809 810TEST(string, memset) { 811 StringTestState<char> state(LARGE); 812 char ch = random () & 255; 813 for (size_t i = 0; i < state.n - 1; i++) { 814 for (size_t j = 0; j < POS_ITER; j++) { 815 state.NewIteration(); 816 817 memset(state.ptr1, ~ch, state.MAX_LEN); 818 memcpy(state.ptr2, state.ptr1, state.MAX_LEN); 819 820 size_t pos = random () % (state.MAX_LEN - state.len[i]); 821 for (size_t k = pos; k < pos + state.len[i]; k++) { 822 state.ptr1[k] = ch; 823 } 824 825 ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos); 826 827 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 828 } 829 } 830} 831 832TEST(string, memmove) { 833 StringTestState<char> state(LARGE); 834 for (size_t i = 0; i < state.n - 1; i++) { 835 for (size_t j = 0; j < POS_ITER; j++) { 836 state.NewIteration(); 837 838 memset(state.ptr1, random() & 255, 2 * state.MAX_LEN); 839 840 size_t pos = random() % (state.MAX_LEN - state.len[i]); 841 842 memset(state.ptr1, random() & 255, state.len[i]); 843 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 844 memcpy(state.ptr, state.ptr1, state.len[i]); 845 memcpy(state.ptr1 + pos, state.ptr, state.len[i]); 846 847 ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos); 848 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN)); 849 } 850 } 851} 852 853TEST(string, bcopy) { 854 StringTestState<char> state(LARGE); 855 for (size_t i = 0; i < state.n; i++) { 856 for (size_t j = 0; j < POS_ITER; j++) { 857 state.NewIteration(); 858 859 memset(state.ptr1, random() & 255, state.MAX_LEN); 860 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN); 861 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 862 863 size_t start = random() % (2 * state.MAX_LEN - state.len[i]); 864 memcpy(state.ptr2 + start, state.ptr1, state.len[i]); 865 866 bcopy(state.ptr1, state.ptr1 + start, state.len[i]); 867 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN)); 868 } 869 } 870} 871 872TEST(string, bzero) { 873 StringTestState<char> state(LARGE); 874 for (size_t j = 0; j < ITER; j++) { 875 state.NewIteration(); 876 877 memset(state.ptr1, random() & 255, state.MAX_LEN); 878 879 size_t start = random() % state.MAX_LEN; 880 size_t end = start + random() % (state.MAX_LEN - start); 881 882 memcpy(state.ptr2, state.ptr1, start); 883 memset(state.ptr2 + start, '\0', end - start); 884 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end); 885 886 bzero(state.ptr1 + start, end - start); 887 888 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 889 } 890} 891 892static void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) { 893 memset(src, (len % 255) + 1, len); 894 memset(dst, 0, len); 895 896 ASSERT_EQ(dst, memcpy(dst, src, len)); 897 ASSERT_TRUE(memcmp(src, dst, len) == 0); 898} 899 900TEST(string, memcpy_align) { 901 RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest); 902} 903 904TEST(string, memcpy_overread) { 905 RunSrcDstBufferOverreadTest(DoMemcpyTest); 906} 907 908static void DoMemsetTest(uint8_t* buf, size_t len) { 909 for (size_t i = 0; i < len; i++) { 910 buf[i] = 0; 911 } 912 int value = (len % 255) + 1; 913 ASSERT_EQ(buf, memset(buf, value, len)); 914 for (size_t i = 0; i < len; i++) { 915 ASSERT_EQ(value, buf[i]); 916 } 917} 918 919TEST(string, memset_align) { 920 RunSingleBufferAlignTest(LARGE, DoMemsetTest); 921} 922 923static void DoStrlenTest(uint8_t* buf, size_t len) { 924 if (len >= 1) { 925 memset(buf, (32 + (len % 96)), len - 1); 926 buf[len-1] = '\0'; 927 ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf))); 928 } 929} 930 931TEST(string, strlen_align) { 932 RunSingleBufferAlignTest(LARGE, DoStrlenTest); 933} 934 935TEST(string, strlen_overread) { 936 RunSingleBufferOverreadTest(DoStrlenTest); 937} 938 939static void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) { 940 if (len >= 1) { 941 memset(src, (32 + (len % 96)), len - 1); 942 src[len-1] = '\0'; 943 memset(dst, 0, len); 944 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst), 945 reinterpret_cast<char*>(src)))); 946 ASSERT_TRUE(memcmp(src, dst, len) == 0); 947 } 948} 949 950TEST(string, strcpy_align) { 951 RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest); 952} 953 954TEST(string, strcpy_overread) { 955 RunSrcDstBufferOverreadTest(DoStrcpyTest); 956} 957 958// Use our own incrementer to cut down on the total number of calls. 959static size_t LargeSetIncrement(size_t len) { 960 if (len >= 4096) { 961 return 4096; 962 } else if (len >= 1024) { 963 return 1024; 964 } else if (len >= 256) { 965 return 256; 966 } 967 return 1; 968} 969 970#define STRCAT_DST_LEN 128 971 972static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) { 973 if (len >= 1) { 974 int value = 32 + (len % 96); 975 memset(src, value, len - 1); 976 src[len-1] = '\0'; 977 978 if (len >= STRCAT_DST_LEN) { 979 // Create a small buffer for doing quick compares in each loop. 980 uint8_t cmp_buf[STRCAT_DST_LEN]; 981 // Make sure dst string contains a different value then the src string. 982 int value2 = 32 + (value + 2) % 96; 983 memset(cmp_buf, value2, sizeof(cmp_buf)); 984 985 for (size_t i = 1; i <= STRCAT_DST_LEN; i++) { 986 memset(dst, value2, i-1); 987 memset(dst+i-1, 0, len-i); 988 src[len-i] = '\0'; 989 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst), 990 reinterpret_cast<char*>(src)))); 991 ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0); 992 ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0); 993 } 994 } else { 995 dst[0] = '\0'; 996 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst), 997 reinterpret_cast<char*>(src)))); 998 ASSERT_TRUE(memcmp(src, dst, len) == 0); 999 } 1000 } 1001} 1002 1003TEST(string, strcat_align) { 1004 RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement); 1005} 1006 1007TEST(string, strcat_overread) { 1008 RunSrcDstBufferOverreadTest(DoStrcatTest); 1009} 1010 1011static void DoStrcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) { 1012 if (len >= 1) { 1013 memset(buf1, (32 + (len % 96)), len - 1); 1014 buf1[len-1] = '\0'; 1015 memset(buf2, (32 + (len % 96)), len - 1); 1016 buf2[len-1] = '\0'; 1017 ASSERT_EQ(0, strcmp(reinterpret_cast<char*>(buf1), 1018 reinterpret_cast<char*>(buf2))); 1019 } 1020} 1021 1022static void DoStrcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) { 1023 // Do string length differences. 1024 int c = (32 + (len1 % 96)); 1025 memset(buf1, c, len1 - 1); 1026 buf1[len1-1] = '\0'; 1027 memset(buf2, c, len2 - 1); 1028 buf2[len2-1] = '\0'; 1029 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1030 reinterpret_cast<char*>(buf2))); 1031 1032 // Do single character differences. 1033 size_t len; 1034 if (len1 > len2) { 1035 len = len2; 1036 } else { 1037 len = len1; 1038 } 1039 // Need at least a two character buffer to do this test. 1040 if (len > 1) { 1041 buf1[len-1] = '\0'; 1042 buf2[len-1] = '\0'; 1043 int diff_c = (c + 1) % 96; 1044 1045 buf1[len-2] = diff_c; 1046 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1047 reinterpret_cast<char*>(buf2))); 1048 1049 buf1[len-2] = c; 1050 buf2[len-2] = diff_c; 1051 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1052 reinterpret_cast<char*>(buf2))); 1053 } 1054} 1055 1056TEST(string, strcmp_align) { 1057 RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement); 1058} 1059 1060TEST(string, strcmp_overread) { 1061 RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest); 1062} 1063 1064static void DoMemcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) { 1065 memset(buf1, len+1, len); 1066 memset(buf2, len+1, len); 1067 ASSERT_EQ(0, memcmp(buf1, buf2, len)); 1068} 1069 1070static void DoMemcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) { 1071 size_t len; 1072 if (len1 > len2) { 1073 len = len2; 1074 } else { 1075 len = len1; 1076 } 1077 1078 memset(buf1, len2+1, len); 1079 buf1[len-1] = len2; 1080 memset(buf2, len2+1, len); 1081 ASSERT_NE(0, memcmp(buf1, buf2, len)); 1082 1083 buf1[len-1] = len2+1; 1084 buf2[len-1] = len2; 1085 ASSERT_NE(0, memcmp(buf1, buf2, len)); 1086} 1087 1088TEST(string, memcmp_align) { 1089 RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement); 1090} 1091 1092TEST(string, memcmp_overread) { 1093 RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest); 1094} 1095