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