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