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 #define KB 1024 24 #define SMALL 1*KB 25 #define LARGE 64*KB 26 27 static int signum(int i) { 28 if (i < 0) { 29 return -1; 30 } else if (i > 0) { 31 return 1; 32 } 33 return 0; 34 } 35 36 TEST(string, strerror) { 37 // Valid. 38 ASSERT_STREQ("Success", strerror(0)); 39 ASSERT_STREQ("Operation not permitted", strerror(1)); 40 41 // Invalid. 42 ASSERT_STREQ("Unknown error -1", strerror(-1)); 43 ASSERT_STREQ("Unknown error 1234", strerror(1234)); 44 } 45 46 #if __BIONIC__ // glibc's strerror isn't thread safe, only its strsignal. 47 48 static void* ConcurrentStrErrorFn(void*) { 49 bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0); 50 return reinterpret_cast<void*>(equal); 51 } 52 53 TEST(string, strerror_concurrent) { 54 const char* strerror1001 = strerror(1001); 55 ASSERT_STREQ("Unknown error 1001", strerror1001); 56 57 pthread_t t; 58 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL)); 59 void* result; 60 ASSERT_EQ(0, pthread_join(t, &result)); 61 ASSERT_TRUE(static_cast<bool>(result)); 62 63 ASSERT_STREQ("Unknown error 1001", strerror1001); 64 } 65 66 #endif 67 68 #if __BIONIC__ // glibc's strerror_r doesn't even have the same signature as the POSIX one. 69 TEST(string, strerror_r) { 70 char buf[256]; 71 72 // Valid. 73 ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf))); 74 ASSERT_STREQ("Success", buf); 75 ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf))); 76 ASSERT_STREQ("Operation not permitted", buf); 77 78 // Invalid. 79 ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf))); 80 ASSERT_STREQ("Unknown error -1", buf); 81 ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf))); 82 ASSERT_STREQ("Unknown error 1234", buf); 83 84 // Buffer too small. 85 ASSERT_EQ(-1, strerror_r(0, buf, 2)); 86 ASSERT_EQ(ERANGE, errno); 87 } 88 #endif 89 90 TEST(string, strsignal) { 91 // A regular signal. 92 ASSERT_STREQ("Hangup", strsignal(1)); 93 94 // A real-time signal. 95 #ifdef __GLIBC__ // glibc reserves real-time signals for internal use, and doesn't count those. 96 ASSERT_STREQ("Real-time signal 14", strsignal(48)); 97 #else 98 ASSERT_STREQ("Real-time signal 16", strsignal(48)); 99 #endif 100 101 // Errors. 102 ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small. 103 ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small. 104 ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large. 105 } 106 107 static void* ConcurrentStrSignalFn(void*) { 108 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0); 109 return reinterpret_cast<void*>(equal); 110 } 111 112 TEST(string, strsignal_concurrent) { 113 const char* strsignal1001 = strsignal(1001); 114 ASSERT_STREQ("Unknown signal 1001", strsignal1001); 115 116 pthread_t t; 117 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL)); 118 void* result; 119 ASSERT_EQ(0, pthread_join(t, &result)); 120 ASSERT_TRUE(static_cast<bool>(result)); 121 122 ASSERT_STREQ("Unknown signal 1001", strsignal1001); 123 } 124 125 // TODO: where did these numbers come from? 126 #define POS_ITER 10 127 #define ITER 500 128 129 // For every length we want to test, vary and change alignment 130 // of allocated memory, fill it with some values, calculate 131 // expected result and then run function and compare what we got. 132 // These tests contributed by Intel Corporation. 133 // TODO: make these tests more intention-revealing and less random. 134 struct StringTestState { 135 StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) { 136 int max_alignment = 64; 137 138 // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN". 139 glob_ptr = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment)); 140 glob_ptr1 = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment)); 141 glob_ptr2 = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment)); 142 143 InitLenArray(); 144 145 srandom(1234); 146 } 147 148 ~StringTestState() { 149 free(glob_ptr); 150 free(glob_ptr1); 151 free(glob_ptr2); 152 } 153 154 void NewIteration() { 155 int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 }; 156 int usable_alignments = 10; 157 int align1 = alignments[random() % (usable_alignments - 1)]; 158 int align2 = alignments[random() % (usable_alignments - 1)]; 159 160 ptr = glob_ptr + align1; 161 ptr1 = glob_ptr1 + align1; 162 ptr2 = glob_ptr2 + align2; 163 } 164 165 const size_t MAX_LEN; 166 char *ptr, *ptr1, *ptr2; 167 size_t n; 168 int len[ITER + 1]; 169 170 private: 171 char *glob_ptr, *glob_ptr1, *glob_ptr2; 172 173 // Calculate input lengths and fill state.len with them. 174 // Test small lengths with more density than big ones. Manually push 175 // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats. 176 // Return number of lengths to test. 177 void InitLenArray() { 178 n = 0; 179 len[n++] = 0; 180 for (size_t i = 1; i < ITER; ++i) { 181 int l = (int) exp(log((double) MAX_LEN) * i / ITER); 182 if (l != len[n - 1]) { 183 len[n++] = l; 184 } 185 } 186 len[n++] = MAX_LEN; 187 } 188 }; 189 190 TEST(string, strcat) { 191 StringTestState state(SMALL); 192 for (size_t i = 1; i < state.n; i++) { 193 for (size_t j = 0; j < POS_ITER; j++) { 194 state.NewIteration(); 195 196 memset(state.ptr2, '\2', state.MAX_LEN); 197 state.ptr2[state.MAX_LEN - 1] = '\0'; 198 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN); 199 200 memset(state.ptr1, random() & 255, state.len[i]); 201 state.ptr1[random() % state.len[i]] = '\0'; 202 state.ptr1[state.len[i] - 1] = '\0'; 203 204 strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1); 205 206 EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2); 207 EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0); 208 } 209 } 210 } 211 212 TEST(string, strchr) { 213 int seek_char = random() & 255; 214 215 StringTestState state(SMALL); 216 for (size_t i = 1; i < state.n; i++) { 217 for (size_t j = 0; j < POS_ITER; j++) { 218 state.NewIteration(); 219 220 if (~seek_char > 0) { 221 memset(state.ptr1, ~seek_char, state.len[i]); 222 } else { 223 memset(state.ptr1, '\1', state.len[i]); 224 } 225 state.ptr1[state.len[i] - 1] = '\0'; 226 227 int pos = random() % state.MAX_LEN; 228 char* expected; 229 if (pos >= state.len[i] - 1) { 230 if (seek_char == 0) { 231 expected = state.ptr1 + state.len[i] - 1; 232 } else { 233 expected = NULL; 234 } 235 } else { 236 state.ptr1[pos] = seek_char; 237 expected = state.ptr1 + pos; 238 } 239 240 ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected); 241 } 242 } 243 } 244 245 TEST(string, strcmp) { 246 StringTestState state(SMALL); 247 for (size_t i = 1; i < state.n; i++) { 248 for (size_t j = 0; j < POS_ITER; j++) { 249 state.NewIteration(); 250 251 memset(state.ptr1, 'v', state.MAX_LEN); 252 memset(state.ptr2, 'n', state.MAX_LEN); 253 state.ptr1[state.len[i] - 1] = '\0'; 254 state.ptr2[state.len[i] - 1] = '\0'; 255 256 int pos = 1 + (random() % (state.MAX_LEN - 1)); 257 int actual; 258 int expected; 259 if (pos >= state.len[i] - 1) { 260 memcpy(state.ptr1, state.ptr2, state.len[i]); 261 expected = 0; 262 actual = strcmp(state.ptr1, state.ptr2); 263 } else { 264 memcpy(state.ptr1, state.ptr2, pos); 265 if (state.ptr1[pos] > state.ptr2[pos]) { 266 expected = 1; 267 } else if (state.ptr1[pos] == state.ptr2[pos]) { 268 state.ptr1[pos + 1] = '\0'; 269 state.ptr2[pos + 1] = '\0'; 270 expected = 0; 271 } else { 272 expected = -1; 273 } 274 actual = strcmp(state.ptr1, state.ptr2); 275 } 276 277 ASSERT_EQ(expected, signum(actual)); 278 } 279 } 280 } 281 282 TEST(string, strcpy) { 283 StringTestState state(SMALL); 284 for (size_t j = 0; j < POS_ITER; j++) { 285 state.NewIteration(); 286 287 size_t pos = random() % state.MAX_LEN; 288 289 memset(state.ptr1, '\2', pos); 290 state.ptr1[pos] = '\0'; 291 state.ptr1[state.MAX_LEN - 1] = '\0'; 292 293 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 294 295 memset(state.ptr2, '\1', state.MAX_LEN); 296 state.ptr2[state.MAX_LEN - 1] = '\0'; 297 298 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN); 299 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 300 state.ptr[2 * state.MAX_LEN - 1] = '\0'; 301 302 ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2); 303 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 || 304 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0)); 305 } 306 } 307 308 309 #if __BIONIC__ 310 // We have to say "DeathTest" here so gtest knows to run this test (which exits) 311 // in its own process. 312 TEST(string_DeathTest, strcpy_fortified) { 313 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; 314 char buf[10]; 315 char *orig = strdup("0123456789"); 316 ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), ""); 317 free(orig); 318 } 319 320 TEST(string_DeathTest, strlen_fortified) { 321 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; 322 char buf[10]; 323 memcpy(buf, "0123456789", sizeof(buf)); 324 ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGSEGV), ""); 325 } 326 327 TEST(string_DeathTest, strchr_fortified) { 328 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; 329 char buf[10]; 330 memcpy(buf, "0123456789", sizeof(buf)); 331 ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), ""); 332 } 333 334 TEST(string_DeathTest, strrchr_fortified) { 335 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; 336 char buf[10]; 337 memcpy(buf, "0123456789", sizeof(buf)); 338 ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), ""); 339 } 340 #endif 341 342 #if __BIONIC__ 343 TEST(string, strlcat) { 344 StringTestState state(SMALL); 345 for (size_t i = 0; i < state.n; i++) { 346 for (size_t j = 0; j < POS_ITER; j++) { 347 state.NewIteration(); 348 349 memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]); 350 state.ptr2[state.MAX_LEN - 1] = '\0'; 351 memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]); 352 353 int pos = random() % state.MAX_LEN; 354 memset(state.ptr1, '\3', pos); 355 state.ptr1[pos] = '\0'; 356 if (pos < state.len[i]) { 357 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1); 358 } else { 359 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]); 360 state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0'; 361 } 362 363 strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]); 364 365 ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0); 366 } 367 } 368 } 369 #endif 370 371 #if __BIONIC__ 372 TEST(string, strlcpy) { 373 StringTestState state(SMALL); 374 for (size_t j = 0; j < POS_ITER; j++) { 375 state.NewIteration(); 376 377 int rand = random() & 255; 378 if (rand < 1) { 379 rand = 1; 380 } 381 memset(state.ptr1, rand, state.MAX_LEN); 382 383 size_t pos = random() % state.MAX_LEN; 384 if (pos < state.MAX_LEN) { 385 state.ptr1[pos] = '\0'; 386 } 387 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 388 389 memset(state.ptr2, random() & 255, state.MAX_LEN); 390 memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN); 391 392 if (pos > state.MAX_LEN - 1) { 393 memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN); 394 state.ptr[2 * state.MAX_LEN - 1] = '\0'; 395 } else { 396 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 397 } 398 399 ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1)); 400 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) || 401 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0)); 402 } 403 } 404 #endif 405 406 TEST(string, strncat) { 407 StringTestState state(SMALL); 408 for (size_t i = 1; i < state.n; i++) { 409 for (size_t j = 0; j < POS_ITER; j++) { 410 state.NewIteration(); 411 412 memset(state.ptr2, '\2', state.MAX_LEN); 413 state.ptr2[state.MAX_LEN - 1] = '\0'; 414 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN); 415 416 memset(state.ptr1, random() & 255, state.len[i]); 417 state.ptr1[random() % state.len[i]] = '\0'; 418 state.ptr1[state.len[i] - 1] = '\0'; 419 420 size_t pos = strlen(state.ptr1); 421 422 size_t actual = random() % state.len[i]; 423 strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos)); 424 state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0'; 425 426 ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2); 427 ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0); 428 } 429 } 430 } 431 432 TEST(string, strncmp) { 433 StringTestState state(SMALL); 434 for (size_t i = 1; i < state.n; i++) { 435 for (size_t j = 0; j < POS_ITER; j++) { 436 state.NewIteration(); 437 438 memset(state.ptr1, 'v', state.MAX_LEN); 439 memset(state.ptr2, 'n', state.MAX_LEN); 440 state.ptr1[state.len[i] - 1] = '\0'; 441 state.ptr2[state.len[i] - 1] = '\0'; 442 443 int pos = 1 + (random() % (state.MAX_LEN - 1)); 444 int actual; 445 int expected; 446 if (pos >= state.len[i] - 1) { 447 memcpy(state.ptr1, state.ptr2, state.len[i]); 448 expected = 0; 449 actual = strncmp(state.ptr1, state.ptr2, state.len[i]); 450 } else { 451 memcpy(state.ptr1, state.ptr2, pos); 452 if (state.ptr1[pos] > state.ptr2[pos]) { 453 expected = 1; 454 } else if (state.ptr1[pos] == state.ptr2[pos]) { 455 state.ptr1[pos + 1] = '\0'; 456 state.ptr2[pos + 1] = '\0'; 457 expected = 0; 458 } else { 459 expected = -1; 460 } 461 actual = strncmp(state.ptr1, state.ptr2, state.len[i]); 462 } 463 464 ASSERT_EQ(expected, signum(actual)); 465 } 466 } 467 } 468 469 TEST(string, strncpy) { 470 StringTestState state(SMALL); 471 for (size_t j = 0; j < ITER; j++) { 472 state.NewIteration(); 473 474 memset(state.ptr1, random() & 255, state.MAX_LEN); 475 state.ptr1[random () % state.MAX_LEN] = '\0'; 476 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 477 478 memset(state.ptr2, '\1', state.MAX_LEN); 479 480 size_t pos; 481 if (memchr(state.ptr1, 0, state.MAX_LEN)) { 482 pos = strlen(state.ptr1); 483 } else { 484 pos = state.MAX_LEN - 1; 485 } 486 487 memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN); 488 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 489 490 ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2); 491 ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 || 492 memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0); 493 } 494 } 495 496 TEST(string, strrchr) { 497 int seek_char = random() & 255; 498 StringTestState state(SMALL); 499 for (size_t i = 1; i < state.n; i++) { 500 for (size_t j = 0; j < POS_ITER; j++) { 501 state.NewIteration(); 502 503 if (~seek_char > 0) { 504 memset(state.ptr1, ~seek_char, state.len[i]); 505 } else { 506 memset(state.ptr1, '\1', state.len[i]); 507 } 508 state.ptr1[state.len[i] - 1] = '\0'; 509 510 int pos = random() % state.MAX_LEN; 511 char* expected; 512 if (pos >= state.len[i] - 1) { 513 if (seek_char == 0) { 514 expected = state.ptr1 + state.len[i] - 1; 515 } else { 516 expected = NULL; 517 } 518 } else { 519 state.ptr1[pos] = seek_char; 520 expected = state.ptr1 + pos; 521 } 522 523 ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected); 524 } 525 } 526 } 527 528 TEST(string, memchr) { 529 int seek_char = random() & 255; 530 StringTestState state(SMALL); 531 for (size_t i = 0; i < state.n; i++) { 532 for (size_t j = 0; j < POS_ITER; j++) { 533 state.NewIteration(); 534 535 memset(state.ptr1, ~seek_char, state.len[i]); 536 537 int pos = random() % state.MAX_LEN; 538 char* expected; 539 if (pos >= state.len[i]) { 540 expected = NULL; 541 } else { 542 state.ptr1[pos] = seek_char; 543 expected = state.ptr1 + pos; 544 } 545 546 ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected); 547 } 548 } 549 } 550 551 TEST(string, memrchr) { 552 int seek_char = random() & 255; 553 StringTestState state(SMALL); 554 for (size_t i = 0; i < state.n; i++) { 555 for (size_t j = 0; j < POS_ITER; j++) { 556 state.NewIteration(); 557 558 memset(state.ptr1, ~seek_char, state.len[i]); 559 560 int pos = random() % state.MAX_LEN; 561 char* expected; 562 if (pos >= state.len[i]) { 563 expected = NULL; 564 } else { 565 state.ptr1[pos] = seek_char; 566 expected = state.ptr1 + pos; 567 } 568 569 ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected); 570 } 571 } 572 } 573 574 TEST(string, memcmp) { 575 StringTestState state(SMALL); 576 for (size_t i = 0; i < state.n; i++) { 577 for (size_t j = 0; j < POS_ITER; j++) { 578 state.NewIteration(); 579 580 int c1 = random() & 0xff; 581 int c2 = random() & 0xff; 582 memset(state.ptr1, c1, state.MAX_LEN); 583 memset(state.ptr2, c1, state.MAX_LEN); 584 585 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]); 586 state.ptr2[pos] = c2; 587 588 int expected = (static_cast<int>(c1) - static_cast<int>(c2)); 589 int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN); 590 591 ASSERT_EQ(signum(expected), signum(actual)); 592 } 593 } 594 } 595 596 TEST(string, memcpy) { 597 StringTestState state(LARGE); 598 int rand = random() & 255; 599 for (size_t i = 0; i < state.n - 1; i++) { 600 for (size_t j = 0; j < POS_ITER; j++) { 601 state.NewIteration(); 602 603 size_t pos = random() % (state.MAX_LEN - state.len[i]); 604 605 memset(state.ptr1, rand, state.len[i]); 606 memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 607 608 memset(state.ptr2, rand, state.len[i]); 609 memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 610 memset(state.ptr2 + pos, '\0', state.len[i]); 611 612 ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos); 613 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 614 } 615 } 616 } 617 618 TEST(string, memset) { 619 StringTestState state(LARGE); 620 char ch = random () & 255; 621 for (size_t i = 0; i < state.n - 1; i++) { 622 for (size_t j = 0; j < POS_ITER; j++) { 623 state.NewIteration(); 624 625 memset(state.ptr1, ~ch, state.MAX_LEN); 626 memcpy(state.ptr2, state.ptr1, state.MAX_LEN); 627 628 size_t pos = random () % (state.MAX_LEN - state.len[i]); 629 for (size_t k = pos; k < pos + state.len[i]; k++) { 630 state.ptr1[k] = ch; 631 } 632 633 ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos); 634 635 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 636 } 637 } 638 } 639 640 TEST(string, memmove) { 641 StringTestState state(LARGE); 642 for (size_t i = 0; i < state.n - 1; i++) { 643 for (size_t j = 0; j < POS_ITER; j++) { 644 state.NewIteration(); 645 646 memset(state.ptr1, random() & 255, 2 * state.MAX_LEN); 647 648 size_t pos = random() % (state.MAX_LEN - state.len[i]); 649 650 memset(state.ptr1, random() & 255, state.len[i]); 651 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 652 memcpy(state.ptr, state.ptr1, state.len[i]); 653 memcpy(state.ptr1 + pos, state.ptr, state.len[i]); 654 655 ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos); 656 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN)); 657 } 658 } 659 } 660 661 TEST(string, bcopy) { 662 StringTestState state(LARGE); 663 for (size_t i = 0; i < state.n; i++) { 664 for (size_t j = 0; j < POS_ITER; j++) { 665 state.NewIteration(); 666 667 memset(state.ptr1, random() & 255, state.MAX_LEN); 668 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN); 669 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 670 671 size_t start = random() % (2 * state.MAX_LEN - state.len[i]); 672 memcpy(state.ptr2 + start, state.ptr1, state.len[i]); 673 674 bcopy(state.ptr1, state.ptr1 + start, state.len[i]); 675 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN)); 676 } 677 } 678 } 679 680 TEST(string, bzero) { 681 StringTestState state(LARGE); 682 for (size_t j = 0; j < ITER; j++) { 683 state.NewIteration(); 684 685 memset(state.ptr1, random() & 255, state.MAX_LEN); 686 687 size_t start = random() % state.MAX_LEN; 688 size_t end = start + random() % (state.MAX_LEN - start); 689 690 memcpy(state.ptr2, state.ptr1, start); 691 memset(state.ptr2 + start, '\0', end - start); 692 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end); 693 694 bzero(state.ptr1 + start, end - start); 695 696 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 697 } 698 } 699