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