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