string_test.cpp revision 6c80ccdeed9d9b30e961f68229fe8171d79c5d14
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(expected, 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 912static void verify_memmove(char* src_copy, char* dst, char* src, size_t size) { 913 memset(dst, 0, size); 914 memcpy(src, src_copy, size); 915 ASSERT_EQ(dst, memmove(dst, src, size)); 916 ASSERT_EQ(0, memcmp(dst, src_copy, size)); 917} 918 919#define MEMMOVE_DATA_SIZE (1024*1024*3) 920 921TEST(string, memmove_check) { 922 char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE)); 923 ASSERT_TRUE(buffer != NULL); 924 925 char* src_data = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE)); 926 ASSERT_TRUE(src_data != NULL); 927 // Initialize to a known pattern to copy into src for each test and 928 // to compare dst against. 929 for (size_t i = 0; i < MEMMOVE_DATA_SIZE; i++) { 930 src_data[i] = (i + 1) % 255; 931 } 932 933 // Check all different dst offsets between 0 and 127 inclusive. 934 char* src = buffer; 935 for (size_t i = 0; i < 127; i++) { 936 char* dst = buffer + 256 + i; 937 // Small copy. 938 verify_memmove(src_data, dst, src, 1024); 939 940 // Medium copy. 941 verify_memmove(src_data, dst, src, 64 * 1024); 942 943 // Medium copy. 944 verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024); 945 } 946 947 // Check all leftover size offsets between 1 and 127 inclusive. 948 char* dst = buffer + 256; 949 src = buffer; 950 for (size_t size = 1; size < 127; size++) { 951 // Small copy. 952 verify_memmove(src_data, dst, src, 1024); 953 954 // Medium copy. 955 verify_memmove(src_data, dst, src, 64 * 1024); 956 957 // Large copy. 958 verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024); 959 } 960} 961 962TEST(string, bcopy) { 963 StringTestState<char> state(LARGE); 964 for (size_t i = 0; i < state.n; i++) { 965 for (size_t j = 0; j < POS_ITER; j++) { 966 state.NewIteration(); 967 968 memset(state.ptr1, random() & 255, state.MAX_LEN); 969 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN); 970 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 971 972 size_t start = random() % (2 * state.MAX_LEN - state.len[i]); 973 memcpy(state.ptr2 + start, state.ptr1, state.len[i]); 974 975 bcopy(state.ptr1, state.ptr1 + start, state.len[i]); 976 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN)); 977 } 978 } 979} 980 981TEST(string, bzero) { 982 StringTestState<char> state(LARGE); 983 for (size_t j = 0; j < ITER; j++) { 984 state.NewIteration(); 985 986 memset(state.ptr1, random() & 255, state.MAX_LEN); 987 988 size_t start = random() % state.MAX_LEN; 989 size_t end = start + random() % (state.MAX_LEN - start); 990 991 memcpy(state.ptr2, state.ptr1, start); 992 memset(state.ptr2 + start, '\0', end - start); 993 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end); 994 995 bzero(state.ptr1 + start, end - start); 996 997 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 998 } 999} 1000 1001static void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) { 1002 memset(src, (len % 255) + 1, len); 1003 memset(dst, 0, len); 1004 1005 ASSERT_EQ(dst, memcpy(dst, src, len)); 1006 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1007} 1008 1009TEST(string, memcpy_align) { 1010 RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest); 1011} 1012 1013TEST(string, memcpy_overread) { 1014 RunSrcDstBufferOverreadTest(DoMemcpyTest); 1015} 1016 1017static void DoMemmoveTest(uint8_t* src, uint8_t* dst, size_t len) { 1018 memset(src, (len % 255) + 1, len); 1019 memset(dst, 0, len); 1020 1021 ASSERT_EQ(dst, memmove(dst, src, len)); 1022 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1023} 1024 1025TEST(string, memmove_align) { 1026 RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest); 1027} 1028 1029TEST(string, memmove_overread) { 1030 RunSrcDstBufferOverreadTest(DoMemmoveTest); 1031} 1032 1033static void DoMemsetTest(uint8_t* buf, size_t len) { 1034 for (size_t i = 0; i < len; i++) { 1035 buf[i] = 0; 1036 } 1037 int value = (len % 255) + 1; 1038 ASSERT_EQ(buf, memset(buf, value, len)); 1039 for (size_t i = 0; i < len; i++) { 1040 ASSERT_EQ(value, buf[i]); 1041 } 1042} 1043 1044TEST(string, memset_align) { 1045 RunSingleBufferAlignTest(LARGE, DoMemsetTest); 1046} 1047 1048static void DoStrlenTest(uint8_t* buf, size_t len) { 1049 if (len >= 1) { 1050 memset(buf, (32 + (len % 96)), len - 1); 1051 buf[len-1] = '\0'; 1052 ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf))); 1053 } 1054} 1055 1056TEST(string, strlen_align) { 1057 RunSingleBufferAlignTest(LARGE, DoStrlenTest); 1058} 1059 1060TEST(string, strlen_overread) { 1061 RunSingleBufferOverreadTest(DoStrlenTest); 1062} 1063 1064static void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) { 1065 if (len >= 1) { 1066 memset(src, (32 + (len % 96)), len - 1); 1067 src[len-1] = '\0'; 1068 memset(dst, 0, len); 1069 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst), 1070 reinterpret_cast<char*>(src)))); 1071 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1072 } 1073} 1074 1075TEST(string, strcpy_align) { 1076 RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest); 1077} 1078 1079TEST(string, strcpy_overread) { 1080 RunSrcDstBufferOverreadTest(DoStrcpyTest); 1081} 1082 1083static void DoStpcpyTest(uint8_t* src, uint8_t* dst, size_t len) { 1084 if (len >= 1) { 1085 memset(src, (32 + (len % 96)), len - 1); 1086 src[len-1] = '\0'; 1087 memset(dst, 0, len); 1088 ASSERT_EQ(dst+len-1, reinterpret_cast<uint8_t*>(stpcpy(reinterpret_cast<char*>(dst), 1089 reinterpret_cast<char*>(src)))); 1090 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1091 } 1092} 1093 1094TEST(string, stpcpy_align) { 1095 RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest); 1096} 1097 1098TEST(string, stpcpy_overread) { 1099 RunSrcDstBufferOverreadTest(DoStpcpyTest); 1100} 1101 1102// Use our own incrementer to cut down on the total number of calls. 1103static size_t LargeSetIncrement(size_t len) { 1104 if (len >= 4096) { 1105 return 4096; 1106 } else if (len >= 1024) { 1107 return 1024; 1108 } else if (len >= 256) { 1109 return 256; 1110 } 1111 return 1; 1112} 1113 1114#define STRCAT_DST_LEN 128 1115 1116static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) { 1117 if (len >= 1) { 1118 int value = 32 + (len % 96); 1119 memset(src, value, len - 1); 1120 src[len-1] = '\0'; 1121 1122 if (len >= STRCAT_DST_LEN) { 1123 // Create a small buffer for doing quick compares in each loop. 1124 uint8_t cmp_buf[STRCAT_DST_LEN]; 1125 // Make sure dst string contains a different value then the src string. 1126 int value2 = 32 + (value + 2) % 96; 1127 memset(cmp_buf, value2, sizeof(cmp_buf)); 1128 1129 for (size_t i = 1; i <= STRCAT_DST_LEN; i++) { 1130 memset(dst, value2, i-1); 1131 memset(dst+i-1, 0, len-i); 1132 src[len-i] = '\0'; 1133 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst), 1134 reinterpret_cast<char*>(src)))); 1135 ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0); 1136 ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0); 1137 } 1138 } else { 1139 dst[0] = '\0'; 1140 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst), 1141 reinterpret_cast<char*>(src)))); 1142 ASSERT_TRUE(memcmp(src, dst, len) == 0); 1143 } 1144 } 1145} 1146 1147TEST(string, strcat_align) { 1148 RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement); 1149} 1150 1151TEST(string, strcat_overread) { 1152 RunSrcDstBufferOverreadTest(DoStrcatTest); 1153} 1154 1155static void DoStrcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) { 1156 if (len >= 1) { 1157 memset(buf1, (32 + (len % 96)), len - 1); 1158 buf1[len-1] = '\0'; 1159 memset(buf2, (32 + (len % 96)), len - 1); 1160 buf2[len-1] = '\0'; 1161 ASSERT_EQ(0, strcmp(reinterpret_cast<char*>(buf1), 1162 reinterpret_cast<char*>(buf2))); 1163 } 1164} 1165 1166static void DoStrcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) { 1167 // Do string length differences. 1168 int c = (32 + (len1 % 96)); 1169 memset(buf1, c, len1 - 1); 1170 buf1[len1-1] = '\0'; 1171 memset(buf2, c, len2 - 1); 1172 buf2[len2-1] = '\0'; 1173 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1174 reinterpret_cast<char*>(buf2))); 1175 1176 // Do single character differences. 1177 size_t len; 1178 if (len1 > len2) { 1179 len = len2; 1180 } else { 1181 len = len1; 1182 } 1183 // Need at least a two character buffer to do this test. 1184 if (len > 1) { 1185 buf1[len-1] = '\0'; 1186 buf2[len-1] = '\0'; 1187 int diff_c = (c + 1) % 96; 1188 1189 buf1[len-2] = diff_c; 1190 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1191 reinterpret_cast<char*>(buf2))); 1192 1193 buf1[len-2] = c; 1194 buf2[len-2] = diff_c; 1195 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1), 1196 reinterpret_cast<char*>(buf2))); 1197 } 1198} 1199 1200TEST(string, strcmp_align) { 1201 RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement); 1202} 1203 1204TEST(string, strcmp_overread) { 1205 RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest); 1206} 1207 1208static void DoMemcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) { 1209 memset(buf1, len+1, len); 1210 memset(buf2, len+1, len); 1211 ASSERT_EQ(0, memcmp(buf1, buf2, len)); 1212} 1213 1214static void DoMemcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) { 1215 size_t len; 1216 if (len1 > len2) { 1217 len = len2; 1218 } else { 1219 len = len1; 1220 } 1221 1222 memset(buf1, len2+1, len); 1223 buf1[len-1] = len2; 1224 memset(buf2, len2+1, len); 1225 ASSERT_NE(0, memcmp(buf1, buf2, len)); 1226 1227 buf1[len-1] = len2+1; 1228 buf2[len-1] = len2; 1229 ASSERT_NE(0, memcmp(buf1, buf2, len)); 1230} 1231 1232TEST(string, memcmp_align) { 1233 RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement); 1234} 1235 1236TEST(string, memcmp_overread) { 1237 RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest); 1238} 1239