string_test.cpp revision 606058933c5129cb1026960ea67624b9426c610f
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 27static 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 36TEST(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 48static void* ConcurrentStrErrorFn(void*) { 49 bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0); 50 return reinterpret_cast<void*>(equal); 51} 52 53TEST(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. 69TEST(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 90TEST(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 107static void* ConcurrentStrSignalFn(void*) { 108 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0); 109 return reinterpret_cast<void*>(equal); 110} 111 112TEST(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. 134struct 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 190TEST(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 212TEST(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 245TEST(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 282TEST(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. 312TEST(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#endif 320 321#if __BIONIC__ 322TEST(string, strlcat) { 323 StringTestState state(SMALL); 324 for (size_t i = 0; i < state.n; i++) { 325 for (size_t j = 0; j < POS_ITER; j++) { 326 state.NewIteration(); 327 328 memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]); 329 state.ptr2[state.MAX_LEN - 1] = '\0'; 330 memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]); 331 332 int pos = random() % state.MAX_LEN; 333 memset(state.ptr1, '\3', pos); 334 state.ptr1[pos] = '\0'; 335 if (pos < state.len[i]) { 336 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1); 337 } else { 338 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]); 339 state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0'; 340 } 341 342 strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]); 343 344 ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0); 345 } 346 } 347} 348#endif 349 350#if __BIONIC__ 351TEST(string, strlcpy) { 352 StringTestState state(SMALL); 353 for (size_t j = 0; j < POS_ITER; j++) { 354 state.NewIteration(); 355 356 int rand = random() & 255; 357 if (rand < 1) { 358 rand = 1; 359 } 360 memset(state.ptr1, rand, state.MAX_LEN); 361 362 size_t pos = random() % state.MAX_LEN; 363 if (pos < state.MAX_LEN) { 364 state.ptr1[pos] = '\0'; 365 } 366 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 367 368 memset(state.ptr2, random() & 255, state.MAX_LEN); 369 memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN); 370 371 if (pos > state.MAX_LEN - 1) { 372 memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN); 373 state.ptr[2 * state.MAX_LEN - 1] = '\0'; 374 } else { 375 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 376 } 377 378 ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1)); 379 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) || 380 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0)); 381 } 382} 383#endif 384 385TEST(string, strncat) { 386 StringTestState state(SMALL); 387 for (size_t i = 1; i < state.n; i++) { 388 for (size_t j = 0; j < POS_ITER; j++) { 389 state.NewIteration(); 390 391 memset(state.ptr2, '\2', state.MAX_LEN); 392 state.ptr2[state.MAX_LEN - 1] = '\0'; 393 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN); 394 395 memset(state.ptr1, random() & 255, state.len[i]); 396 state.ptr1[random() % state.len[i]] = '\0'; 397 state.ptr1[state.len[i] - 1] = '\0'; 398 399 size_t pos = strlen(state.ptr1); 400 401 size_t actual = random() % state.len[i]; 402 strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos)); 403 state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0'; 404 405 ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2); 406 ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0); 407 } 408 } 409} 410 411TEST(string, strncmp) { 412 StringTestState state(SMALL); 413 for (size_t i = 1; i < state.n; i++) { 414 for (size_t j = 0; j < POS_ITER; j++) { 415 state.NewIteration(); 416 417 memset(state.ptr1, 'v', state.MAX_LEN); 418 memset(state.ptr2, 'n', state.MAX_LEN); 419 state.ptr1[state.len[i] - 1] = '\0'; 420 state.ptr2[state.len[i] - 1] = '\0'; 421 422 int pos = 1 + (random() % (state.MAX_LEN - 1)); 423 int actual; 424 int expected; 425 if (pos >= state.len[i] - 1) { 426 memcpy(state.ptr1, state.ptr2, state.len[i]); 427 expected = 0; 428 actual = strncmp(state.ptr1, state.ptr2, state.len[i]); 429 } else { 430 memcpy(state.ptr1, state.ptr2, pos); 431 if (state.ptr1[pos] > state.ptr2[pos]) { 432 expected = 1; 433 } else if (state.ptr1[pos] == state.ptr2[pos]) { 434 state.ptr1[pos + 1] = '\0'; 435 state.ptr2[pos + 1] = '\0'; 436 expected = 0; 437 } else { 438 expected = -1; 439 } 440 actual = strncmp(state.ptr1, state.ptr2, state.len[i]); 441 } 442 443 ASSERT_EQ(expected, signum(actual)); 444 } 445 } 446} 447 448TEST(string, strncpy) { 449 StringTestState state(SMALL); 450 for (size_t j = 0; j < ITER; j++) { 451 state.NewIteration(); 452 453 memset(state.ptr1, random() & 255, state.MAX_LEN); 454 state.ptr1[random () % state.MAX_LEN] = '\0'; 455 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 456 457 memset(state.ptr2, '\1', state.MAX_LEN); 458 459 size_t pos; 460 if (memchr(state.ptr1, 0, state.MAX_LEN)) { 461 pos = strlen(state.ptr1); 462 } else { 463 pos = state.MAX_LEN - 1; 464 } 465 466 memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN); 467 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 468 469 ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2); 470 ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 || 471 memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0); 472 } 473} 474 475TEST(string, strrchr) { 476 int seek_char = random() & 255; 477 StringTestState state(SMALL); 478 for (size_t i = 1; i < state.n; i++) { 479 for (size_t j = 0; j < POS_ITER; j++) { 480 state.NewIteration(); 481 482 if (~seek_char > 0) { 483 memset(state.ptr1, ~seek_char, state.len[i]); 484 } else { 485 memset(state.ptr1, '\1', state.len[i]); 486 } 487 state.ptr1[state.len[i] - 1] = '\0'; 488 489 int pos = random() % state.MAX_LEN; 490 char* expected; 491 if (pos >= state.len[i] - 1) { 492 if (seek_char == 0) { 493 expected = state.ptr1 + state.len[i] - 1; 494 } else { 495 expected = NULL; 496 } 497 } else { 498 state.ptr1[pos] = seek_char; 499 expected = state.ptr1 + pos; 500 } 501 502 ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected); 503 } 504 } 505} 506 507TEST(string, memchr) { 508 int seek_char = random() & 255; 509 StringTestState state(SMALL); 510 for (size_t i = 0; i < state.n; i++) { 511 for (size_t j = 0; j < POS_ITER; j++) { 512 state.NewIteration(); 513 514 memset(state.ptr1, ~seek_char, state.len[i]); 515 516 int pos = random() % state.MAX_LEN; 517 char* expected; 518 if (pos >= state.len[i]) { 519 expected = NULL; 520 } else { 521 state.ptr1[pos] = seek_char; 522 expected = state.ptr1 + pos; 523 } 524 525 ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected); 526 } 527 } 528} 529 530TEST(string, memrchr) { 531 int seek_char = random() & 255; 532 StringTestState state(SMALL); 533 for (size_t i = 0; i < state.n; i++) { 534 for (size_t j = 0; j < POS_ITER; j++) { 535 state.NewIteration(); 536 537 memset(state.ptr1, ~seek_char, state.len[i]); 538 539 int pos = random() % state.MAX_LEN; 540 char* expected; 541 if (pos >= state.len[i]) { 542 expected = NULL; 543 } else { 544 state.ptr1[pos] = seek_char; 545 expected = state.ptr1 + pos; 546 } 547 548 ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected); 549 } 550 } 551} 552 553TEST(string, memcmp) { 554 StringTestState state(SMALL); 555 for (size_t i = 0; i < state.n; i++) { 556 for (size_t j = 0; j < POS_ITER; j++) { 557 state.NewIteration(); 558 559 int c1 = random() & 0xff; 560 int c2 = random() & 0xff; 561 memset(state.ptr1, c1, state.MAX_LEN); 562 memset(state.ptr2, c1, state.MAX_LEN); 563 564 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]); 565 state.ptr2[pos] = c2; 566 567 int expected = (static_cast<int>(c1) - static_cast<int>(c2)); 568 int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN); 569 570 ASSERT_EQ(signum(expected), signum(actual)); 571 } 572 } 573} 574 575TEST(string, memcpy) { 576 StringTestState state(LARGE); 577 int rand = random() & 255; 578 for (size_t i = 0; i < state.n - 1; i++) { 579 for (size_t j = 0; j < POS_ITER; j++) { 580 state.NewIteration(); 581 582 size_t pos = random() % (state.MAX_LEN - state.len[i]); 583 584 memset(state.ptr1, rand, state.len[i]); 585 memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 586 587 memset(state.ptr2, rand, state.len[i]); 588 memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 589 memset(state.ptr2 + pos, '\0', state.len[i]); 590 591 ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos); 592 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 593 } 594 } 595} 596 597TEST(string, memset) { 598 StringTestState state(LARGE); 599 char ch = random () & 255; 600 for (size_t i = 0; i < state.n - 1; i++) { 601 for (size_t j = 0; j < POS_ITER; j++) { 602 state.NewIteration(); 603 604 memset(state.ptr1, ~ch, state.MAX_LEN); 605 memcpy(state.ptr2, state.ptr1, state.MAX_LEN); 606 607 size_t pos = random () % (state.MAX_LEN - state.len[i]); 608 for (size_t k = pos; k < pos + state.len[i]; k++) { 609 state.ptr1[k] = ch; 610 } 611 612 ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos); 613 614 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 615 } 616 } 617} 618 619TEST(string, memmove) { 620 StringTestState state(LARGE); 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, random() & 255, 2 * state.MAX_LEN); 626 627 size_t pos = random() % (state.MAX_LEN - state.len[i]); 628 629 memset(state.ptr1, random() & 255, state.len[i]); 630 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 631 memcpy(state.ptr, state.ptr1, state.len[i]); 632 memcpy(state.ptr1 + pos, state.ptr, state.len[i]); 633 634 ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos); 635 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN)); 636 } 637 } 638} 639 640TEST(string, bcopy) { 641 StringTestState state(LARGE); 642 for (size_t i = 0; i < state.n; i++) { 643 for (size_t j = 0; j < POS_ITER; j++) { 644 state.NewIteration(); 645 646 memset(state.ptr1, random() & 255, state.MAX_LEN); 647 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN); 648 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 649 650 size_t start = random() % (2 * state.MAX_LEN - state.len[i]); 651 memcpy(state.ptr2 + start, state.ptr1, state.len[i]); 652 653 bcopy(state.ptr1, state.ptr1 + start, state.len[i]); 654 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN)); 655 } 656 } 657} 658 659TEST(string, bzero) { 660 StringTestState state(LARGE); 661 for (size_t j = 0; j < ITER; j++) { 662 state.NewIteration(); 663 664 memset(state.ptr1, random() & 255, state.MAX_LEN); 665 666 size_t start = random() % state.MAX_LEN; 667 size_t end = start + random() % (state.MAX_LEN - start); 668 669 memcpy(state.ptr2, state.ptr1, start); 670 memset(state.ptr2 + start, '\0', end - start); 671 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end); 672 673 bzero(state.ptr1 + start, end - start); 674 675 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 676 } 677} 678