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 31 static 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 40 TEST(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__) 51 static 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. 58 TEST(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 75 TEST(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 99 TEST(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 114 static void* ConcurrentStrSignalFn(void*) { 115 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0); 116 return reinterpret_cast<void*>(equal); 117 } 118 119 TEST(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. 141 template<class Character> 142 struct 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 size_t 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 size_t l = static_cast<size_t>(exp(log(static_cast<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 198 TEST(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 221 TEST(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 230 TEST(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 244 TEST(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 254 TEST(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 263 TEST(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 277 TEST(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 286 TEST(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 299 TEST(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 309 TEST(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 322 TEST(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 335 TEST(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 345 TEST(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 355 TEST(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 362 TEST(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 380 TEST(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 size_t 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 413 TEST(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 size_t 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 450 TEST(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 476 TEST(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 502 TEST(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 size_t 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 533 TEST(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 570 TEST(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 596 TEST(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 size_t 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 633 TEST(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 672 TEST(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 711 TEST(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 size_t 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 743 TEST(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 size_t 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 766 TEST(string, memchr_zero) { 767 uint8_t* buffer; 768 ASSERT_EQ(0, posix_memalign(reinterpret_cast<void**>(&buffer), 64, 64)); 769 memset(buffer, 10, 64); 770 ASSERT_TRUE(NULL == memchr(buffer, 5, 0)); 771 ASSERT_TRUE(NULL == memchr(buffer, 10, 0)); 772 } 773 774 TEST(string, memrchr) { 775 int seek_char = random() & 255; 776 StringTestState<char> state(SMALL); 777 for (size_t i = 0; i < state.n; i++) { 778 for (size_t j = 0; j < POS_ITER; j++) { 779 state.NewIteration(); 780 781 memset(state.ptr1, ~seek_char, state.len[i]); 782 783 size_t pos = random() % state.MAX_LEN; 784 char* expected; 785 if (pos >= state.len[i]) { 786 expected = NULL; 787 } else { 788 state.ptr1[pos] = seek_char; 789 expected = state.ptr1 + pos; 790 } 791 792 ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected); 793 } 794 } 795 } 796 797 TEST(string, memcmp) { 798 StringTestState<char> state(SMALL); 799 for (size_t i = 0; i < state.n; i++) { 800 for (size_t j = 0; j < POS_ITER; j++) { 801 state.NewIteration(); 802 803 int c1 = random() & 0xff; 804 int c2 = random() & 0xff; 805 memset(state.ptr1, c1, state.MAX_LEN); 806 memset(state.ptr2, c1, state.MAX_LEN); 807 808 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]); 809 state.ptr2[pos] = c2; 810 811 int expected = (static_cast<int>(c1) - static_cast<int>(c2)); 812 int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN); 813 814 ASSERT_EQ(signum(expected), signum(actual)); 815 } 816 } 817 } 818 819 TEST(string, wmemcmp) { 820 StringTestState<wchar_t> state(SMALL); 821 822 for (size_t i = 0; i < state.n; i++) { 823 for (size_t j = 0; j < POS_ITER; j++) { 824 state.NewIteration(); 825 826 long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1; 827 int c1 = rand() & mask; 828 int c2 = rand() & mask; 829 wmemset(state.ptr1, c1, state.MAX_LEN); 830 wmemset(state.ptr2, c1, state.MAX_LEN); 831 832 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]); 833 state.ptr2[pos] = c2; 834 835 int expected = (static_cast<int>(c1) - static_cast<int>(c2)); 836 int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN); 837 838 ASSERT_EQ(signum(expected), signum(actual)); 839 } 840 } 841 } 842 843 TEST(string, memcpy) { 844 StringTestState<char> state(LARGE); 845 int rand = random() & 255; 846 for (size_t i = 0; i < state.n - 1; i++) { 847 for (size_t j = 0; j < POS_ITER; j++) { 848 state.NewIteration(); 849 850 size_t pos = random() % (state.MAX_LEN - state.len[i]); 851 852 memset(state.ptr1, rand, state.len[i]); 853 memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 854 855 memset(state.ptr2, rand, state.len[i]); 856 memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 857 memset(state.ptr2 + pos, '\0', state.len[i]); 858 859 ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos); 860 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 861 } 862 } 863 } 864 865 TEST(string, memset) { 866 StringTestState<char> state(LARGE); 867 char ch = random () & 255; 868 for (size_t i = 0; i < state.n - 1; i++) { 869 for (size_t j = 0; j < POS_ITER; j++) { 870 state.NewIteration(); 871 872 memset(state.ptr1, ~ch, state.MAX_LEN); 873 memcpy(state.ptr2, state.ptr1, state.MAX_LEN); 874 875 size_t pos = random () % (state.MAX_LEN - state.len[i]); 876 for (size_t k = pos; k < pos + state.len[i]; k++) { 877 state.ptr1[k] = ch; 878 } 879 880 ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos); 881 882 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 883 } 884 } 885 } 886 887 TEST(string, memmove) { 888 StringTestState<char> state(LARGE); 889 for (size_t i = 0; i < state.n - 1; i++) { 890 for (size_t j = 0; j < POS_ITER; j++) { 891 state.NewIteration(); 892 893 memset(state.ptr1, random() & 255, 2 * state.MAX_LEN); 894 895 size_t pos = random() % (state.MAX_LEN - state.len[i]); 896 897 memset(state.ptr1, random() & 255, state.len[i]); 898 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 899 memcpy(state.ptr, state.ptr1, state.len[i]); 900 memcpy(state.ptr1 + pos, state.ptr, state.len[i]); 901 902 ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos); 903 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN)); 904 } 905 } 906 } 907 908 TEST(string, memmove_cache_size) { 909 size_t len = 600000; 910 int max_alignment = 31; 911 int alignments[] = {0, 5, 11, 29, 30}; 912 char* ptr = reinterpret_cast<char*>(malloc(sizeof(char) * len)); 913 char* ptr1 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len)); 914 char* glob_ptr2 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len + max_alignment)); 915 size_t pos = 64; 916 917 ASSERT_TRUE(ptr != NULL); 918 ASSERT_TRUE(ptr1 != NULL); 919 ASSERT_TRUE(glob_ptr2 != NULL); 920 921 for (int i = 0; i < 5; i++) { 922 char* ptr2 = glob_ptr2 + alignments[i]; 923 memset(ptr1, random() & 255, 2 * len); 924 memset(ptr1, random() & 255, len); 925 memcpy(ptr2, ptr1, 2 * len); 926 memcpy(ptr, ptr1, len); 927 memcpy(ptr1 + pos, ptr, len); 928 929 ASSERT_TRUE(memmove(ptr2 + pos, ptr, len) == ptr2 + pos); 930 ASSERT_EQ(0, memcmp(ptr2, ptr1, 2 * len)); 931 } 932 free(ptr); 933 free(ptr1); 934 free(glob_ptr2); 935 } 936 937 static void verify_memmove(char* src_copy, char* dst, char* src, size_t size) { 938 memset(dst, 0, size); 939 memcpy(src, src_copy, size); 940 ASSERT_EQ(dst, memmove(dst, src, size)); 941 ASSERT_EQ(0, memcmp(dst, src_copy, size)); 942 } 943 944 #define MEMMOVE_DATA_SIZE (1024*1024*3) 945 946 TEST(string, memmove_check) { 947 char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE)); 948 ASSERT_TRUE(buffer != NULL); 949 950 char* src_data = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE)); 951 ASSERT_TRUE(src_data != NULL); 952 // Initialize to a known pattern to copy into src for each test and 953 // to compare dst against. 954 for (size_t i = 0; i < MEMMOVE_DATA_SIZE; i++) { 955 src_data[i] = (i + 1) % 255; 956 } 957 958 // Check all different dst offsets between 0 and 127 inclusive. 959 char* src = buffer; 960 for (size_t i = 0; i < 127; i++) { 961 char* dst = buffer + 256 + i; 962 // Small copy. 963 verify_memmove(src_data, dst, src, 1024); 964 965 // Medium copy. 966 verify_memmove(src_data, dst, src, 64 * 1024); 967 968 // Medium copy. 969 verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024); 970 } 971 972 // Check all leftover size offsets between 1 and 127 inclusive. 973 char* dst = buffer + 256; 974 src = buffer; 975 for (size_t size = 1; size < 127; size++) { 976 // Small copy. 977 verify_memmove(src_data, dst, src, 1024); 978 979 // Medium copy. 980 verify_memmove(src_data, dst, src, 64 * 1024); 981 982 // Large copy. 983 verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024); 984 } 985 } 986 987 TEST(string, bcopy) { 988 StringTestState<char> state(LARGE); 989 for (size_t i = 0; i < state.n; i++) { 990 for (size_t j = 0; j < POS_ITER; j++) { 991 state.NewIteration(); 992 993 memset(state.ptr1, random() & 255, state.MAX_LEN); 994 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN); 995 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 996 997 size_t start = random() % (2 * state.MAX_LEN - state.len[i]); 998 memcpy(state.ptr2 + start, state.ptr1, state.len[i]); 999 1000 bcopy(state.ptr1, state.ptr1 + start, state.len[i]); 1001 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN)); 1002 } 1003 } 1004 } 1005 1006 TEST(string, bzero) { 1007 StringTestState<char> state(LARGE); 1008 for (size_t j = 0; j < ITER; j++) { 1009 state.NewIteration(); 1010 1011 memset(state.ptr1, random() & 255, state.MAX_LEN); 1012 1013 size_t start = random() % state.MAX_LEN; 1014 size_t end = start + random() % (state.MAX_LEN - start); 1015 1016 memcpy(state.ptr2, state.ptr1, start); 1017 memset(state.ptr2 + start, '\0', end - start); 1018 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end); 1019 1020 bzero(state.ptr1 + start, end - start); 1021 1022 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 1023 } 1024 } 1025 1026 static void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) { 1027 memset(src, (len % 255) + 1, len); 1028 memset(dst, 0, len); 1029 1030 ASSERT_EQ(dst, memcpy(dst, src, len)); 1031 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1032 } 1033 1034 TEST(string, memcpy_align) { 1035 RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest); 1036 } 1037 1038 TEST(string, memcpy_overread) { 1039 RunSrcDstBufferOverreadTest(DoMemcpyTest); 1040 } 1041 1042 static void DoMemmoveTest(uint8_t* src, uint8_t* dst, size_t len) { 1043 memset(src, (len % 255) + 1, len); 1044 memset(dst, 0, len); 1045 1046 ASSERT_EQ(dst, memmove(dst, src, len)); 1047 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1048 } 1049 1050 TEST(string, memmove_align) { 1051 RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest); 1052 } 1053 1054 TEST(string, memmove_overread) { 1055 RunSrcDstBufferOverreadTest(DoMemmoveTest); 1056 } 1057 1058 static void DoMemsetTest(uint8_t* buf, size_t len) { 1059 for (size_t i = 0; i < len; i++) { 1060 buf[i] = 0; 1061 } 1062 int value = (len % 255) + 1; 1063 ASSERT_EQ(buf, memset(buf, value, len)); 1064 for (size_t i = 0; i < len; i++) { 1065 ASSERT_EQ(value, buf[i]); 1066 } 1067 } 1068 1069 TEST(string, memset_align) { 1070 RunSingleBufferAlignTest(LARGE, DoMemsetTest); 1071 } 1072 1073 static void DoStrlenTest(uint8_t* buf, size_t len) { 1074 if (len >= 1) { 1075 memset(buf, (32 + (len % 96)), len - 1); 1076 buf[len-1] = '\0'; 1077 ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf))); 1078 } 1079 } 1080 1081 TEST(string, strlen_align) { 1082 RunSingleBufferAlignTest(LARGE, DoStrlenTest); 1083 } 1084 1085 TEST(string, strlen_overread) { 1086 RunSingleBufferOverreadTest(DoStrlenTest); 1087 } 1088 1089 static void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) { 1090 if (len >= 1) { 1091 memset(src, (32 + (len % 96)), len - 1); 1092 src[len-1] = '\0'; 1093 memset(dst, 0, len); 1094 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst), 1095 reinterpret_cast<char*>(src)))); 1096 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1097 } 1098 } 1099 1100 TEST(string, strcpy_align) { 1101 RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest); 1102 } 1103 1104 TEST(string, strcpy_overread) { 1105 RunSrcDstBufferOverreadTest(DoStrcpyTest); 1106 } 1107 1108 static void DoStpcpyTest(uint8_t* src, uint8_t* dst, size_t len) { 1109 if (len >= 1) { 1110 memset(src, (32 + (len % 96)), len - 1); 1111 src[len-1] = '\0'; 1112 memset(dst, 0, len); 1113 ASSERT_EQ(dst+len-1, reinterpret_cast<uint8_t*>(stpcpy(reinterpret_cast<char*>(dst), 1114 reinterpret_cast<char*>(src)))); 1115 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1116 } 1117 } 1118 1119 TEST(string, stpcpy_align) { 1120 RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest); 1121 } 1122 1123 TEST(string, stpcpy_overread) { 1124 RunSrcDstBufferOverreadTest(DoStpcpyTest); 1125 } 1126 1127 // Use our own incrementer to cut down on the total number of calls. 1128 static size_t LargeSetIncrement(size_t len) { 1129 if (len >= 4096) { 1130 return 4096; 1131 } else if (len >= 1024) { 1132 return 1024; 1133 } else if (len >= 256) { 1134 return 256; 1135 } 1136 return 1; 1137 } 1138 1139 #define STRCAT_DST_LEN 128 1140 1141 static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) { 1142 if (len >= 1) { 1143 int value = 32 + (len % 96); 1144 memset(src, value, len - 1); 1145 src[len-1] = '\0'; 1146 1147 if (len >= STRCAT_DST_LEN) { 1148 // Create a small buffer for doing quick compares in each loop. 1149 uint8_t cmp_buf[STRCAT_DST_LEN]; 1150 // Make sure dst string contains a different value then the src string. 1151 int value2 = 32 + (value + 2) % 96; 1152 memset(cmp_buf, value2, sizeof(cmp_buf)); 1153 1154 for (size_t i = 1; i <= STRCAT_DST_LEN; i++) { 1155 memset(dst, value2, i-1); 1156 memset(dst+i-1, 0, len-i); 1157 src[len-i] = '\0'; 1158 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst), 1159 reinterpret_cast<char*>(src)))); 1160 ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0); 1161 ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0); 1162 } 1163 } else { 1164 dst[0] = '\0'; 1165 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst), 1166 reinterpret_cast<char*>(src)))); 1167 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1168 } 1169 } 1170 } 1171 1172 TEST(string, strcat_align) { 1173 RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement); 1174 } 1175 1176 TEST(string, strcat_overread) { 1177 RunSrcDstBufferOverreadTest(DoStrcatTest); 1178 } 1179 1180 static void DoStrcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) { 1181 if (len >= 1) { 1182 memset(buf1, (32 + (len % 96)), len - 1); 1183 buf1[len-1] = '\0'; 1184 memset(buf2, (32 + (len % 96)), len - 1); 1185 buf2[len-1] = '\0'; 1186 ASSERT_EQ(0, strcmp(reinterpret_cast<char*>(buf1), 1187 reinterpret_cast<char*>(buf2))); 1188 } 1189 } 1190 1191 static void DoStrcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) { 1192 // Do string length differences. 1193 int c = (32 + (len1 % 96)); 1194 memset(buf1, c, len1 - 1); 1195 buf1[len1-1] = '\0'; 1196 memset(buf2, c, len2 - 1); 1197 buf2[len2-1] = '\0'; 1198 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1199 reinterpret_cast<char*>(buf2))); 1200 1201 // Do single character differences. 1202 size_t len; 1203 if (len1 > len2) { 1204 len = len2; 1205 } else { 1206 len = len1; 1207 } 1208 // Need at least a two character buffer to do this test. 1209 if (len > 1) { 1210 buf1[len-1] = '\0'; 1211 buf2[len-1] = '\0'; 1212 int diff_c = (c + 1) % 96; 1213 1214 buf1[len-2] = diff_c; 1215 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1216 reinterpret_cast<char*>(buf2))); 1217 1218 buf1[len-2] = c; 1219 buf2[len-2] = diff_c; 1220 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1221 reinterpret_cast<char*>(buf2))); 1222 } 1223 } 1224 1225 TEST(string, strcmp_align) { 1226 RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement); 1227 } 1228 1229 TEST(string, strcmp_overread) { 1230 RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest); 1231 } 1232 1233 static void DoMemcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) { 1234 memset(buf1, len+1, len); 1235 memset(buf2, len+1, len); 1236 ASSERT_EQ(0, memcmp(buf1, buf2, len)); 1237 } 1238 1239 static void DoMemcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) { 1240 size_t len; 1241 if (len1 > len2) { 1242 len = len2; 1243 } else { 1244 len = len1; 1245 } 1246 1247 memset(buf1, len2+1, len); 1248 buf1[len-1] = len2; 1249 memset(buf2, len2+1, len); 1250 ASSERT_NE(0, memcmp(buf1, buf2, len)); 1251 1252 buf1[len-1] = len2+1; 1253 buf2[len-1] = len2; 1254 ASSERT_NE(0, memcmp(buf1, buf2, len)); 1255 } 1256 1257 TEST(string, memcmp_align) { 1258 RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement); 1259 } 1260 1261 TEST(string, memcmp_overread) { 1262 RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest); 1263 } 1264 1265 static void DoStrchrTest(uint8_t* buf, size_t len) { 1266 if (len >= 1) { 1267 char value = 32 + (len % 96); 1268 char search_value = 33 + (len % 96); 1269 memset(buf, value, len - 1); 1270 buf[len-1] = '\0'; 1271 ASSERT_EQ(NULL, strchr(reinterpret_cast<char*>(buf), search_value)); 1272 ASSERT_EQ(reinterpret_cast<char*>(&buf[len-1]), strchr(reinterpret_cast<char*>(buf), '\0')); 1273 if (len >= 2) { 1274 buf[0] = search_value; 1275 ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strchr(reinterpret_cast<char*>(buf), search_value)); 1276 buf[0] = value; 1277 buf[len-2] = search_value; 1278 ASSERT_EQ(reinterpret_cast<char*>(&buf[len-2]), strchr(reinterpret_cast<char*>(buf), search_value)); 1279 } 1280 } 1281 } 1282 1283 TEST(string, strchr_align) { 1284 RunSingleBufferAlignTest(MEDIUM, DoStrchrTest); 1285 } 1286 1287 TEST(string, strchr_overread) { 1288 RunSingleBufferOverreadTest(DoStrchrTest); 1289 } 1290