Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <gtest/gtest.h>
     18 
     19 #include <errno.h>
     20 #include <math.h>
     21 #include <string.h>
     22 
     23 #define KB 1024
     24 #define SMALL 1*KB
     25 #define LARGE 64*KB
     26 
     27 static int signum(int i) {
     28   if (i < 0) {
     29     return -1;
     30   } else if (i > 0) {
     31     return 1;
     32   }
     33   return 0;
     34 }
     35 
     36 TEST(string, strerror) {
     37   // Valid.
     38   ASSERT_STREQ("Success", strerror(0));
     39   ASSERT_STREQ("Operation not permitted", strerror(1));
     40 
     41   // Invalid.
     42   ASSERT_STREQ("Unknown error -1", strerror(-1));
     43   ASSERT_STREQ("Unknown error 1234", strerror(1234));
     44 }
     45 
     46 #if __BIONIC__ // glibc's strerror isn't thread safe, only its strsignal.
     47 
     48 static void* ConcurrentStrErrorFn(void*) {
     49   bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
     50   return reinterpret_cast<void*>(equal);
     51 }
     52 
     53 TEST(string, strerror_concurrent) {
     54   const char* strerror1001 = strerror(1001);
     55   ASSERT_STREQ("Unknown error 1001", strerror1001);
     56 
     57   pthread_t t;
     58   ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL));
     59   void* result;
     60   ASSERT_EQ(0, pthread_join(t, &result));
     61   ASSERT_TRUE(static_cast<bool>(result));
     62 
     63   ASSERT_STREQ("Unknown error 1001", strerror1001);
     64 }
     65 
     66 #endif
     67 
     68 #if __BIONIC__ // glibc's strerror_r doesn't even have the same signature as the POSIX one.
     69 TEST(string, strerror_r) {
     70   char buf[256];
     71 
     72   // Valid.
     73   ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf)));
     74   ASSERT_STREQ("Success", buf);
     75   ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf)));
     76   ASSERT_STREQ("Operation not permitted", buf);
     77 
     78   // Invalid.
     79   ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf)));
     80   ASSERT_STREQ("Unknown error -1", buf);
     81   ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf)));
     82   ASSERT_STREQ("Unknown error 1234", buf);
     83 
     84   // Buffer too small.
     85   ASSERT_EQ(-1, strerror_r(0, buf, 2));
     86   ASSERT_EQ(ERANGE, errno);
     87 }
     88 #endif
     89 
     90 TEST(string, strsignal) {
     91   // A regular signal.
     92   ASSERT_STREQ("Hangup", strsignal(1));
     93 
     94   // A real-time signal.
     95 #ifdef __GLIBC__ // glibc reserves real-time signals for internal use, and doesn't count those.
     96   ASSERT_STREQ("Real-time signal 14", strsignal(48));
     97 #else
     98   ASSERT_STREQ("Real-time signal 16", strsignal(48));
     99 #endif
    100 
    101   // Errors.
    102   ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
    103   ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small.
    104   ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large.
    105 }
    106 
    107 static void* ConcurrentStrSignalFn(void*) {
    108   bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
    109   return reinterpret_cast<void*>(equal);
    110 }
    111 
    112 TEST(string, strsignal_concurrent) {
    113   const char* strsignal1001 = strsignal(1001);
    114   ASSERT_STREQ("Unknown signal 1001", strsignal1001);
    115 
    116   pthread_t t;
    117   ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL));
    118   void* result;
    119   ASSERT_EQ(0, pthread_join(t, &result));
    120   ASSERT_TRUE(static_cast<bool>(result));
    121 
    122   ASSERT_STREQ("Unknown signal 1001", strsignal1001);
    123 }
    124 
    125 // TODO: where did these numbers come from?
    126 #define POS_ITER    10
    127 #define ITER        500
    128 
    129 // For every length we want to test, vary and change alignment
    130 // of allocated memory, fill it with some values, calculate
    131 // expected result and then run function and compare what we got.
    132 // These tests contributed by Intel Corporation.
    133 // TODO: make these tests more intention-revealing and less random.
    134 struct StringTestState {
    135   StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) {
    136     int max_alignment = 64;
    137 
    138     // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
    139     glob_ptr = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment));
    140     glob_ptr1 = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment));
    141     glob_ptr2 = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment));
    142 
    143     InitLenArray();
    144 
    145     srandom(1234);
    146   }
    147 
    148   ~StringTestState() {
    149     free(glob_ptr);
    150     free(glob_ptr1);
    151     free(glob_ptr2);
    152   }
    153 
    154   void NewIteration() {
    155     int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 };
    156     int usable_alignments = 10;
    157     int align1 = alignments[random() % (usable_alignments - 1)];
    158     int align2 = alignments[random() % (usable_alignments - 1)];
    159 
    160     ptr = glob_ptr + align1;
    161     ptr1 = glob_ptr1 + align1;
    162     ptr2 = glob_ptr2 + align2;
    163   }
    164 
    165   const size_t MAX_LEN;
    166   char *ptr, *ptr1, *ptr2;
    167   size_t n;
    168   int len[ITER + 1];
    169 
    170  private:
    171   char *glob_ptr, *glob_ptr1, *glob_ptr2;
    172 
    173   // Calculate input lengths and fill state.len with them.
    174   // Test small lengths with more density than big ones. Manually push
    175   // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
    176   // Return number of lengths to test.
    177   void InitLenArray() {
    178     n = 0;
    179     len[n++] = 0;
    180     for (size_t i = 1; i < ITER; ++i) {
    181       int l = (int) exp(log((double) MAX_LEN) * i / ITER);
    182       if (l != len[n - 1]) {
    183         len[n++] = l;
    184       }
    185     }
    186     len[n++] = MAX_LEN;
    187   }
    188 };
    189 
    190 TEST(string, strcat) {
    191   StringTestState state(SMALL);
    192   for (size_t i = 1; i < state.n; i++) {
    193     for (size_t j = 0; j < POS_ITER; j++) {
    194       state.NewIteration();
    195 
    196       memset(state.ptr2, '\2', state.MAX_LEN);
    197       state.ptr2[state.MAX_LEN - 1] = '\0';
    198       memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
    199 
    200       memset(state.ptr1, random() & 255, state.len[i]);
    201       state.ptr1[random() % state.len[i]] = '\0';
    202       state.ptr1[state.len[i] - 1] = '\0';
    203 
    204       strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
    205 
    206       EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
    207       EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
    208     }
    209   }
    210 }
    211 
    212 TEST(string, strchr) {
    213   int seek_char = random() & 255;
    214 
    215   StringTestState state(SMALL);
    216   for (size_t i = 1; i < state.n; i++) {
    217     for (size_t j = 0; j < POS_ITER; j++) {
    218       state.NewIteration();
    219 
    220       if (~seek_char > 0) {
    221         memset(state.ptr1, ~seek_char, state.len[i]);
    222       } else {
    223         memset(state.ptr1, '\1', state.len[i]);
    224       }
    225       state.ptr1[state.len[i] - 1] = '\0';
    226 
    227       int pos = random() % state.MAX_LEN;
    228       char* expected;
    229       if (pos >= state.len[i] - 1) {
    230         if (seek_char == 0) {
    231           expected = state.ptr1 + state.len[i] - 1;
    232         } else {
    233           expected = NULL;
    234         }
    235       } else {
    236         state.ptr1[pos] = seek_char;
    237         expected = state.ptr1 + pos;
    238       }
    239 
    240       ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
    241     }
    242   }
    243 }
    244 
    245 TEST(string, strcmp) {
    246   StringTestState state(SMALL);
    247   for (size_t i = 1; i < state.n; i++) {
    248     for (size_t j = 0; j < POS_ITER; j++) {
    249       state.NewIteration();
    250 
    251       memset(state.ptr1, 'v', state.MAX_LEN);
    252       memset(state.ptr2, 'n', state.MAX_LEN);
    253       state.ptr1[state.len[i] - 1] = '\0';
    254       state.ptr2[state.len[i] - 1] = '\0';
    255 
    256       int pos = 1 + (random() % (state.MAX_LEN - 1));
    257       int actual;
    258       int expected;
    259       if (pos >= state.len[i] - 1) {
    260         memcpy(state.ptr1, state.ptr2, state.len[i]);
    261         expected = 0;
    262         actual = strcmp(state.ptr1, state.ptr2);
    263       } else {
    264         memcpy(state.ptr1, state.ptr2, pos);
    265         if (state.ptr1[pos] > state.ptr2[pos]) {
    266           expected = 1;
    267         } else if (state.ptr1[pos] == state.ptr2[pos]) {
    268           state.ptr1[pos + 1] = '\0';
    269           state.ptr2[pos + 1] = '\0';
    270           expected = 0;
    271         } else {
    272           expected = -1;
    273         }
    274         actual = strcmp(state.ptr1, state.ptr2);
    275       }
    276 
    277       ASSERT_EQ(expected, signum(actual));
    278     }
    279   }
    280 }
    281 
    282 TEST(string, strcpy) {
    283   StringTestState state(SMALL);
    284   for (size_t j = 0; j < POS_ITER; j++) {
    285     state.NewIteration();
    286 
    287     size_t pos = random() % state.MAX_LEN;
    288 
    289     memset(state.ptr1, '\2', pos);
    290     state.ptr1[pos] = '\0';
    291     state.ptr1[state.MAX_LEN - 1] = '\0';
    292 
    293     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    294 
    295     memset(state.ptr2, '\1', state.MAX_LEN);
    296     state.ptr2[state.MAX_LEN - 1] = '\0';
    297 
    298     memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
    299     memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    300     state.ptr[2 * state.MAX_LEN - 1] = '\0';
    301 
    302     ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
    303     ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
    304                  (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
    305   }
    306 }
    307 
    308 
    309 #if __BIONIC__
    310 // We have to say "DeathTest" here so gtest knows to run this test (which exits)
    311 // in its own process.
    312 TEST(string_DeathTest, strcpy_fortified) {
    313   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    314   char buf[10];
    315   char *orig = strdup("0123456789");
    316   ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
    317   free(orig);
    318 }
    319 
    320 TEST(string_DeathTest, strlen_fortified) {
    321   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    322   char buf[10];
    323   memcpy(buf, "0123456789", sizeof(buf));
    324   ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGSEGV), "");
    325 }
    326 
    327 TEST(string_DeathTest, strchr_fortified) {
    328   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    329   char buf[10];
    330   memcpy(buf, "0123456789", sizeof(buf));
    331   ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
    332 }
    333 
    334 TEST(string_DeathTest, strrchr_fortified) {
    335   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    336   char buf[10];
    337   memcpy(buf, "0123456789", sizeof(buf));
    338   ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
    339 }
    340 #endif
    341 
    342 #if __BIONIC__
    343 TEST(string, strlcat) {
    344   StringTestState state(SMALL);
    345   for (size_t i = 0; i < state.n; i++) {
    346     for (size_t j = 0; j < POS_ITER; j++) {
    347       state.NewIteration();
    348 
    349       memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
    350       state.ptr2[state.MAX_LEN - 1] = '\0';
    351       memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
    352 
    353       int pos = random() % state.MAX_LEN;
    354       memset(state.ptr1, '\3', pos);
    355       state.ptr1[pos] = '\0';
    356       if (pos < state.len[i]) {
    357         memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
    358       } else {
    359         memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
    360         state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
    361       }
    362 
    363       strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
    364 
    365       ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
    366     }
    367   }
    368 }
    369 #endif
    370 
    371 #if __BIONIC__
    372 TEST(string, strlcpy) {
    373   StringTestState state(SMALL);
    374   for (size_t j = 0; j < POS_ITER; j++) {
    375     state.NewIteration();
    376 
    377     int rand = random() & 255;
    378     if (rand < 1) {
    379       rand = 1;
    380     }
    381     memset(state.ptr1, rand, state.MAX_LEN);
    382 
    383     size_t pos = random() % state.MAX_LEN;
    384     if (pos < state.MAX_LEN) {
    385       state.ptr1[pos] = '\0';
    386     }
    387     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    388 
    389     memset(state.ptr2, random() & 255, state.MAX_LEN);
    390     memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
    391 
    392     if (pos > state.MAX_LEN - 1) {
    393       memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
    394       state.ptr[2 * state.MAX_LEN - 1] = '\0';
    395     } else {
    396       memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    397     }
    398 
    399     ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
    400     ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
    401                  (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
    402   }
    403 }
    404 #endif
    405 
    406 TEST(string, strncat) {
    407   StringTestState state(SMALL);
    408   for (size_t i = 1; i < state.n; i++) {
    409     for (size_t j = 0; j < POS_ITER; j++) {
    410       state.NewIteration();
    411 
    412       memset(state.ptr2, '\2', state.MAX_LEN);
    413       state.ptr2[state.MAX_LEN - 1] = '\0';
    414       memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
    415 
    416       memset(state.ptr1, random() & 255, state.len[i]);
    417       state.ptr1[random() % state.len[i]] = '\0';
    418       state.ptr1[state.len[i] - 1] = '\0';
    419 
    420       size_t pos = strlen(state.ptr1);
    421 
    422       size_t actual = random() % state.len[i];
    423       strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
    424       state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
    425 
    426       ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
    427       ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
    428     }
    429   }
    430 }
    431 
    432 TEST(string, strncmp) {
    433   StringTestState state(SMALL);
    434   for (size_t i = 1; i < state.n; i++) {
    435     for (size_t j = 0; j < POS_ITER; j++) {
    436       state.NewIteration();
    437 
    438       memset(state.ptr1, 'v', state.MAX_LEN);
    439       memset(state.ptr2, 'n', state.MAX_LEN);
    440       state.ptr1[state.len[i] - 1] = '\0';
    441       state.ptr2[state.len[i] - 1] = '\0';
    442 
    443       int pos = 1 + (random() % (state.MAX_LEN - 1));
    444       int actual;
    445       int expected;
    446       if (pos >= state.len[i] - 1) {
    447         memcpy(state.ptr1, state.ptr2, state.len[i]);
    448         expected = 0;
    449         actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
    450       } else {
    451         memcpy(state.ptr1, state.ptr2, pos);
    452         if (state.ptr1[pos] > state.ptr2[pos]) {
    453           expected = 1;
    454         } else if (state.ptr1[pos] == state.ptr2[pos]) {
    455           state.ptr1[pos + 1] = '\0';
    456           state.ptr2[pos + 1] = '\0';
    457           expected = 0;
    458         } else {
    459           expected = -1;
    460         }
    461         actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
    462       }
    463 
    464       ASSERT_EQ(expected, signum(actual));
    465     }
    466   }
    467 }
    468 
    469 TEST(string, strncpy) {
    470   StringTestState state(SMALL);
    471   for (size_t j = 0; j < ITER; j++) {
    472     state.NewIteration();
    473 
    474     memset(state.ptr1, random() & 255, state.MAX_LEN);
    475     state.ptr1[random () % state.MAX_LEN] = '\0';
    476     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    477 
    478     memset(state.ptr2, '\1', state.MAX_LEN);
    479 
    480     size_t pos;
    481     if (memchr(state.ptr1, 0, state.MAX_LEN)) {
    482       pos = strlen(state.ptr1);
    483     } else {
    484       pos = state.MAX_LEN - 1;
    485     }
    486 
    487     memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN);
    488     memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    489 
    490     ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2);
    491     ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 ||
    492                  memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0);
    493   }
    494 }
    495 
    496 TEST(string, strrchr) {
    497   int seek_char = random() & 255;
    498   StringTestState state(SMALL);
    499   for (size_t i = 1; i < state.n; i++) {
    500     for (size_t j = 0; j < POS_ITER; j++) {
    501       state.NewIteration();
    502 
    503       if (~seek_char > 0) {
    504         memset(state.ptr1, ~seek_char, state.len[i]);
    505       } else {
    506         memset(state.ptr1, '\1', state.len[i]);
    507       }
    508       state.ptr1[state.len[i] - 1] = '\0';
    509 
    510       int pos = random() % state.MAX_LEN;
    511       char* expected;
    512       if (pos >= state.len[i] - 1) {
    513         if (seek_char == 0) {
    514           expected = state.ptr1 + state.len[i] - 1;
    515         } else {
    516           expected = NULL;
    517         }
    518       } else {
    519         state.ptr1[pos] = seek_char;
    520         expected = state.ptr1 + pos;
    521       }
    522 
    523       ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
    524     }
    525   }
    526 }
    527 
    528 TEST(string, memchr) {
    529   int seek_char = random() & 255;
    530   StringTestState state(SMALL);
    531   for (size_t i = 0; i < state.n; i++) {
    532     for (size_t j = 0; j < POS_ITER; j++) {
    533       state.NewIteration();
    534 
    535       memset(state.ptr1, ~seek_char, state.len[i]);
    536 
    537       int pos = random() % state.MAX_LEN;
    538       char* expected;
    539       if (pos >= state.len[i]) {
    540         expected = NULL;
    541       } else {
    542         state.ptr1[pos] = seek_char;
    543         expected = state.ptr1 + pos;
    544       }
    545 
    546       ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
    547     }
    548   }
    549 }
    550 
    551 TEST(string, memrchr) {
    552   int seek_char = random() & 255;
    553   StringTestState state(SMALL);
    554   for (size_t i = 0; i < state.n; i++) {
    555     for (size_t j = 0; j < POS_ITER; j++) {
    556       state.NewIteration();
    557 
    558       memset(state.ptr1, ~seek_char, state.len[i]);
    559 
    560       int pos = random() % state.MAX_LEN;
    561       char* expected;
    562       if (pos >= state.len[i]) {
    563         expected = NULL;
    564       } else {
    565         state.ptr1[pos] = seek_char;
    566         expected = state.ptr1 + pos;
    567       }
    568 
    569       ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
    570     }
    571   }
    572 }
    573 
    574 TEST(string, memcmp) {
    575   StringTestState state(SMALL);
    576   for (size_t i = 0; i < state.n; i++) {
    577     for (size_t j = 0; j < POS_ITER; j++) {
    578       state.NewIteration();
    579 
    580       int c1 = random() & 0xff;
    581       int c2 = random() & 0xff;
    582       memset(state.ptr1, c1, state.MAX_LEN);
    583       memset(state.ptr2, c1, state.MAX_LEN);
    584 
    585       int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
    586       state.ptr2[pos] = c2;
    587 
    588       int expected = (static_cast<int>(c1) - static_cast<int>(c2));
    589       int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
    590 
    591       ASSERT_EQ(signum(expected), signum(actual));
    592     }
    593   }
    594 }
    595 
    596 TEST(string, memcpy) {
    597   StringTestState state(LARGE);
    598   int rand = random() & 255;
    599   for (size_t i = 0; i < state.n - 1; i++) {
    600     for (size_t j = 0; j < POS_ITER; j++) {
    601       state.NewIteration();
    602 
    603       size_t pos = random() % (state.MAX_LEN - state.len[i]);
    604 
    605       memset(state.ptr1, rand, state.len[i]);
    606       memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
    607 
    608       memset(state.ptr2, rand, state.len[i]);
    609       memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
    610       memset(state.ptr2 + pos, '\0', state.len[i]);
    611 
    612       ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
    613       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
    614     }
    615   }
    616 }
    617 
    618 TEST(string, memset) {
    619   StringTestState state(LARGE);
    620   char ch = random () & 255;
    621   for (size_t i = 0; i < state.n - 1; i++) {
    622     for (size_t j = 0; j < POS_ITER; j++) {
    623       state.NewIteration();
    624 
    625       memset(state.ptr1, ~ch, state.MAX_LEN);
    626       memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
    627 
    628       size_t pos = random () % (state.MAX_LEN - state.len[i]);
    629       for (size_t k = pos; k < pos + state.len[i]; k++) {
    630         state.ptr1[k] = ch;
    631       }
    632 
    633       ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
    634 
    635       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
    636     }
    637   }
    638 }
    639 
    640 TEST(string, memmove) {
    641   StringTestState state(LARGE);
    642   for (size_t i = 0; i < state.n - 1; i++) {
    643     for (size_t j = 0; j < POS_ITER; j++) {
    644       state.NewIteration();
    645 
    646       memset(state.ptr1, random() & 255, 2 * state.MAX_LEN);
    647 
    648       size_t pos = random() % (state.MAX_LEN - state.len[i]);
    649 
    650       memset(state.ptr1, random() & 255, state.len[i]);
    651       memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
    652       memcpy(state.ptr, state.ptr1, state.len[i]);
    653       memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
    654 
    655       ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
    656       ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
    657     }
    658   }
    659 }
    660 
    661 TEST(string, bcopy) {
    662   StringTestState state(LARGE);
    663   for (size_t i = 0; i < state.n; i++) {
    664     for (size_t j = 0; j < POS_ITER; j++) {
    665       state.NewIteration();
    666 
    667       memset(state.ptr1, random() & 255, state.MAX_LEN);
    668       memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN);
    669       memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
    670 
    671       size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
    672       memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
    673 
    674       bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
    675       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
    676     }
    677   }
    678 }
    679 
    680 TEST(string, bzero) {
    681   StringTestState state(LARGE);
    682   for (size_t j = 0; j < ITER; j++) {
    683     state.NewIteration();
    684 
    685     memset(state.ptr1, random() & 255, state.MAX_LEN);
    686 
    687     size_t start = random() % state.MAX_LEN;
    688     size_t end = start + random() % (state.MAX_LEN - start);
    689 
    690     memcpy(state.ptr2, state.ptr1, start);
    691     memset(state.ptr2 + start, '\0', end - start);
    692     memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
    693 
    694     bzero(state.ptr1 + start, end - start);
    695 
    696     ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
    697   }
    698 }
    699