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 template<class Character>
    135 struct StringTestState {
    136   StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) {
    137     int max_alignment = 64;
    138 
    139     // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
    140     glob_ptr = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
    141     glob_ptr1 = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
    142     glob_ptr2 = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
    143 
    144     InitLenArray();
    145 
    146     srandom(1234);
    147   }
    148 
    149   ~StringTestState() {
    150     free(glob_ptr);
    151     free(glob_ptr1);
    152     free(glob_ptr2);
    153   }
    154 
    155   void NewIteration() {
    156     int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 };
    157     int usable_alignments = 10;
    158     int align1 = alignments[random() % (usable_alignments - 1)];
    159     int align2 = alignments[random() % (usable_alignments - 1)];
    160 
    161     ptr = glob_ptr + align1;
    162     ptr1 = glob_ptr1 + align1;
    163     ptr2 = glob_ptr2 + align2;
    164   }
    165 
    166   const size_t MAX_LEN;
    167   Character *ptr, *ptr1, *ptr2;
    168   size_t n;
    169   int len[ITER + 1];
    170 
    171  private:
    172   Character *glob_ptr, *glob_ptr1, *glob_ptr2;
    173 
    174   // Calculate input lengths and fill state.len with them.
    175   // Test small lengths with more density than big ones. Manually push
    176   // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
    177   // Return number of lengths to test.
    178   void InitLenArray() {
    179     n = 0;
    180     len[n++] = 0;
    181     for (size_t i = 1; i < ITER; ++i) {
    182       int l = (int) exp(log((double) MAX_LEN) * i / ITER);
    183       if (l != len[n - 1]) {
    184         len[n++] = l;
    185       }
    186     }
    187     len[n++] = MAX_LEN;
    188   }
    189 };
    190 
    191 TEST(string, strcat) {
    192   StringTestState<char> state(SMALL);
    193   for (size_t i = 1; i < state.n; i++) {
    194     for (size_t j = 0; j < POS_ITER; j++) {
    195       state.NewIteration();
    196 
    197       memset(state.ptr2, '\2', state.MAX_LEN);
    198       state.ptr2[state.MAX_LEN - 1] = '\0';
    199       memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
    200 
    201       memset(state.ptr1, random() & 255, state.len[i]);
    202       state.ptr1[random() % state.len[i]] = '\0';
    203       state.ptr1[state.len[i] - 1] = '\0';
    204 
    205       strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
    206 
    207       EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
    208       EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
    209     }
    210   }
    211 }
    212 
    213 // one byte target with "\0" source
    214 TEST(string, strcpy2) {
    215   char buf[1];
    216   char* orig = strdup("");
    217   strcpy(buf, orig);
    218   ASSERT_EQ('\0', buf[0]);
    219   free(orig);
    220 }
    221 
    222 // multibyte target where we under fill target
    223 TEST(string, strcpy3) {
    224   char buf[10];
    225   char* orig = strdup("12345");
    226   memset(buf, 'A', sizeof(buf));
    227   strcpy(buf, orig);
    228   ASSERT_EQ('1',  buf[0]);
    229   ASSERT_EQ('2',  buf[1]);
    230   ASSERT_EQ('3',  buf[2]);
    231   ASSERT_EQ('4',  buf[3]);
    232   ASSERT_EQ('5',  buf[4]);
    233   ASSERT_EQ('\0', buf[5]);
    234   ASSERT_EQ('A',  buf[6]);
    235   ASSERT_EQ('A',  buf[7]);
    236   ASSERT_EQ('A',  buf[8]);
    237   ASSERT_EQ('A',  buf[9]);
    238   free(orig);
    239 }
    240 
    241 // multibyte target where we fill target exactly
    242 TEST(string, strcpy4) {
    243   char buf[10];
    244   char* orig = strdup("123456789");
    245   memset(buf, 'A', sizeof(buf));
    246   strcpy(buf, orig);
    247   ASSERT_EQ('1',  buf[0]);
    248   ASSERT_EQ('2',  buf[1]);
    249   ASSERT_EQ('3',  buf[2]);
    250   ASSERT_EQ('4',  buf[3]);
    251   ASSERT_EQ('5',  buf[4]);
    252   ASSERT_EQ('6',  buf[5]);
    253   ASSERT_EQ('7',  buf[6]);
    254   ASSERT_EQ('8',  buf[7]);
    255   ASSERT_EQ('9',  buf[8]);
    256   ASSERT_EQ('\0', buf[9]);
    257   free(orig);
    258 }
    259 
    260 TEST(string, strcat2) {
    261   char buf[10];
    262   memset(buf, 'A', sizeof(buf));
    263   buf[0] = 'a';
    264   buf[1] = '\0';
    265   char* res = strcat(buf, "01234");
    266   ASSERT_EQ(buf, res);
    267   ASSERT_EQ('a',  buf[0]);
    268   ASSERT_EQ('0',  buf[1]);
    269   ASSERT_EQ('1',  buf[2]);
    270   ASSERT_EQ('2',  buf[3]);
    271   ASSERT_EQ('3',  buf[4]);
    272   ASSERT_EQ('4',  buf[5]);
    273   ASSERT_EQ('\0', buf[6]);
    274   ASSERT_EQ('A',  buf[7]);
    275   ASSERT_EQ('A',  buf[8]);
    276   ASSERT_EQ('A',  buf[9]);
    277 }
    278 
    279 TEST(string, strcat3) {
    280   char buf[10];
    281   memset(buf, 'A', sizeof(buf));
    282   buf[0] = 'a';
    283   buf[1] = '\0';
    284   char* res = strcat(buf, "01234567");
    285   ASSERT_EQ(buf, res);
    286   ASSERT_EQ('a',  buf[0]);
    287   ASSERT_EQ('0',  buf[1]);
    288   ASSERT_EQ('1',  buf[2]);
    289   ASSERT_EQ('2',  buf[3]);
    290   ASSERT_EQ('3',  buf[4]);
    291   ASSERT_EQ('4',  buf[5]);
    292   ASSERT_EQ('5', buf[6]);
    293   ASSERT_EQ('6',  buf[7]);
    294   ASSERT_EQ('7',  buf[8]);
    295   ASSERT_EQ('\0',  buf[9]);
    296 }
    297 
    298 TEST(string, strncat2) {
    299   char buf[10];
    300   memset(buf, 'A', sizeof(buf));
    301   buf[0] = 'a';
    302   buf[1] = '\0';
    303   char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1);
    304   ASSERT_EQ(buf, res);
    305   ASSERT_EQ('a',  buf[0]);
    306   ASSERT_EQ('0',  buf[1]);
    307   ASSERT_EQ('1',  buf[2]);
    308   ASSERT_EQ('2',  buf[3]);
    309   ASSERT_EQ('3',  buf[4]);
    310   ASSERT_EQ('4',  buf[5]);
    311   ASSERT_EQ('\0', buf[6]);
    312   ASSERT_EQ('A',  buf[7]);
    313   ASSERT_EQ('A',  buf[8]);
    314   ASSERT_EQ('A',  buf[9]);
    315 }
    316 
    317 TEST(string, strncat3) {
    318   char buf[10];
    319   memset(buf, 'A', sizeof(buf));
    320   buf[0] = 'a';
    321   buf[1] = '\0';
    322   char* res = strncat(buf, "0123456789", 5);
    323   ASSERT_EQ(buf, res);
    324   ASSERT_EQ('a',  buf[0]);
    325   ASSERT_EQ('0',  buf[1]);
    326   ASSERT_EQ('1',  buf[2]);
    327   ASSERT_EQ('2',  buf[3]);
    328   ASSERT_EQ('3',  buf[4]);
    329   ASSERT_EQ('4',  buf[5]);
    330   ASSERT_EQ('\0', buf[6]);
    331   ASSERT_EQ('A',  buf[7]);
    332   ASSERT_EQ('A',  buf[8]);
    333   ASSERT_EQ('A',  buf[9]);
    334 }
    335 
    336 TEST(string, strncat4) {
    337   char buf[10];
    338   memset(buf, 'A', sizeof(buf));
    339   buf[0] = 'a';
    340   buf[1] = '\0';
    341   char* res = strncat(buf, "01234567", 8);
    342   ASSERT_EQ(buf, res);
    343   ASSERT_EQ('a',  buf[0]);
    344   ASSERT_EQ('0',  buf[1]);
    345   ASSERT_EQ('1',  buf[2]);
    346   ASSERT_EQ('2',  buf[3]);
    347   ASSERT_EQ('3',  buf[4]);
    348   ASSERT_EQ('4',  buf[5]);
    349   ASSERT_EQ('5', buf[6]);
    350   ASSERT_EQ('6',  buf[7]);
    351   ASSERT_EQ('7',  buf[8]);
    352   ASSERT_EQ('\0',  buf[9]);
    353 }
    354 
    355 TEST(string, strncat5) {
    356   char buf[10];
    357   memset(buf, 'A', sizeof(buf));
    358   buf[0] = 'a';
    359   buf[1] = '\0';
    360   char* res = strncat(buf, "01234567", 9);
    361   ASSERT_EQ(buf, res);
    362   ASSERT_EQ('a',  buf[0]);
    363   ASSERT_EQ('0',  buf[1]);
    364   ASSERT_EQ('1',  buf[2]);
    365   ASSERT_EQ('2',  buf[3]);
    366   ASSERT_EQ('3',  buf[4]);
    367   ASSERT_EQ('4',  buf[5]);
    368   ASSERT_EQ('5', buf[6]);
    369   ASSERT_EQ('6',  buf[7]);
    370   ASSERT_EQ('7',  buf[8]);
    371   ASSERT_EQ('\0',  buf[9]);
    372 }
    373 
    374 TEST(string, strchr_with_0) {
    375   char buf[10];
    376   const char* s = "01234";
    377   memcpy(buf, s, strlen(s) + 1);
    378   EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
    379 }
    380 
    381 TEST(string, strchr) {
    382   int seek_char = random() & 255;
    383 
    384   StringTestState<char> state(SMALL);
    385   for (size_t i = 1; i < state.n; i++) {
    386     for (size_t j = 0; j < POS_ITER; j++) {
    387       state.NewIteration();
    388 
    389       if (~seek_char > 0) {
    390         memset(state.ptr1, ~seek_char, state.len[i]);
    391       } else {
    392         memset(state.ptr1, '\1', state.len[i]);
    393       }
    394       state.ptr1[state.len[i] - 1] = '\0';
    395 
    396       int pos = random() % state.MAX_LEN;
    397       char* expected;
    398       if (pos >= state.len[i] - 1) {
    399         if (seek_char == 0) {
    400           expected = state.ptr1 + state.len[i] - 1;
    401         } else {
    402           expected = NULL;
    403         }
    404       } else {
    405         state.ptr1[pos] = seek_char;
    406         expected = state.ptr1 + pos;
    407       }
    408 
    409       ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
    410     }
    411   }
    412 }
    413 
    414 TEST(string, strcmp) {
    415   StringTestState<char> state(SMALL);
    416   for (size_t i = 1; i < state.n; i++) {
    417     for (size_t j = 0; j < POS_ITER; j++) {
    418       state.NewIteration();
    419 
    420       memset(state.ptr1, 'v', state.MAX_LEN);
    421       memset(state.ptr2, 'n', state.MAX_LEN);
    422       state.ptr1[state.len[i] - 1] = '\0';
    423       state.ptr2[state.len[i] - 1] = '\0';
    424 
    425       int pos = 1 + (random() % (state.MAX_LEN - 1));
    426       int actual;
    427       int expected;
    428       if (pos >= state.len[i] - 1) {
    429         memcpy(state.ptr1, state.ptr2, state.len[i]);
    430         expected = 0;
    431         actual = strcmp(state.ptr1, state.ptr2);
    432       } else {
    433         memcpy(state.ptr1, state.ptr2, pos);
    434         if (state.ptr1[pos] > state.ptr2[pos]) {
    435           expected = 1;
    436         } else if (state.ptr1[pos] == state.ptr2[pos]) {
    437           state.ptr1[pos + 1] = '\0';
    438           state.ptr2[pos + 1] = '\0';
    439           expected = 0;
    440         } else {
    441           expected = -1;
    442         }
    443         actual = strcmp(state.ptr1, state.ptr2);
    444       }
    445 
    446       ASSERT_EQ(expected, signum(actual));
    447     }
    448   }
    449 }
    450 
    451 TEST(string, strcpy) {
    452   StringTestState<char> state(SMALL);
    453   for (size_t j = 0; j < POS_ITER; j++) {
    454     state.NewIteration();
    455 
    456     size_t pos = random() % state.MAX_LEN;
    457 
    458     memset(state.ptr1, '\2', pos);
    459     state.ptr1[pos] = '\0';
    460     state.ptr1[state.MAX_LEN - 1] = '\0';
    461 
    462     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    463 
    464     memset(state.ptr2, '\1', state.MAX_LEN);
    465     state.ptr2[state.MAX_LEN - 1] = '\0';
    466 
    467     memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
    468     memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    469     state.ptr[2 * state.MAX_LEN - 1] = '\0';
    470 
    471     ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
    472     ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
    473                  (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
    474   }
    475 }
    476 
    477 
    478 #if __BIONIC__
    479 TEST(string, strlcat) {
    480   StringTestState<char> state(SMALL);
    481   for (size_t i = 0; i < state.n; i++) {
    482     for (size_t j = 0; j < POS_ITER; j++) {
    483       state.NewIteration();
    484 
    485       memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
    486       state.ptr2[state.MAX_LEN - 1] = '\0';
    487       memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
    488 
    489       int pos = random() % state.MAX_LEN;
    490       memset(state.ptr1, '\3', pos);
    491       state.ptr1[pos] = '\0';
    492       if (pos < state.len[i]) {
    493         memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
    494       } else {
    495         memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
    496         state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
    497       }
    498 
    499       strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
    500 
    501       ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
    502     }
    503   }
    504 }
    505 #endif
    506 
    507 #if __BIONIC__
    508 TEST(string, strlcpy) {
    509   StringTestState<char> state(SMALL);
    510   for (size_t j = 0; j < POS_ITER; j++) {
    511     state.NewIteration();
    512 
    513     int rand = random() & 255;
    514     if (rand < 1) {
    515       rand = 1;
    516     }
    517     memset(state.ptr1, rand, state.MAX_LEN);
    518 
    519     size_t pos = random() % state.MAX_LEN;
    520     if (pos < state.MAX_LEN) {
    521       state.ptr1[pos] = '\0';
    522     }
    523     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    524 
    525     memset(state.ptr2, random() & 255, state.MAX_LEN);
    526     memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
    527 
    528     if (pos > state.MAX_LEN - 1) {
    529       memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
    530       state.ptr[2 * state.MAX_LEN - 1] = '\0';
    531     } else {
    532       memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    533     }
    534 
    535     ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
    536     ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
    537                  (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
    538   }
    539 }
    540 #endif
    541 
    542 TEST(string, strncat) {
    543   StringTestState<char> state(SMALL);
    544   for (size_t i = 1; i < state.n; i++) {
    545     for (size_t j = 0; j < POS_ITER; j++) {
    546       state.NewIteration();
    547 
    548       memset(state.ptr2, '\2', state.MAX_LEN);
    549       state.ptr2[state.MAX_LEN - 1] = '\0';
    550       memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
    551 
    552       memset(state.ptr1, random() & 255, state.len[i]);
    553       state.ptr1[random() % state.len[i]] = '\0';
    554       state.ptr1[state.len[i] - 1] = '\0';
    555 
    556       size_t pos = strlen(state.ptr1);
    557 
    558       size_t actual = random() % state.len[i];
    559       strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
    560       state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
    561 
    562       ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
    563       ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
    564     }
    565   }
    566 }
    567 
    568 TEST(string, strncmp) {
    569   StringTestState<char> state(SMALL);
    570   for (size_t i = 1; i < state.n; i++) {
    571     for (size_t j = 0; j < POS_ITER; j++) {
    572       state.NewIteration();
    573 
    574       memset(state.ptr1, 'v', state.MAX_LEN);
    575       memset(state.ptr2, 'n', state.MAX_LEN);
    576       state.ptr1[state.len[i] - 1] = '\0';
    577       state.ptr2[state.len[i] - 1] = '\0';
    578 
    579       int pos = 1 + (random() % (state.MAX_LEN - 1));
    580       int actual;
    581       int expected;
    582       if (pos >= state.len[i] - 1) {
    583         memcpy(state.ptr1, state.ptr2, state.len[i]);
    584         expected = 0;
    585         actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
    586       } else {
    587         memcpy(state.ptr1, state.ptr2, pos);
    588         if (state.ptr1[pos] > state.ptr2[pos]) {
    589           expected = 1;
    590         } else if (state.ptr1[pos] == state.ptr2[pos]) {
    591           state.ptr1[pos + 1] = '\0';
    592           state.ptr2[pos + 1] = '\0';
    593           expected = 0;
    594         } else {
    595           expected = -1;
    596         }
    597         actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
    598       }
    599 
    600       ASSERT_EQ(expected, signum(actual));
    601     }
    602   }
    603 }
    604 
    605 TEST(string, strncpy) {
    606   StringTestState<char> state(SMALL);
    607   for (size_t j = 0; j < ITER; j++) {
    608     state.NewIteration();
    609 
    610     memset(state.ptr1, random() & 255, state.MAX_LEN);
    611     state.ptr1[random () % state.MAX_LEN] = '\0';
    612     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    613 
    614     memset(state.ptr2, '\1', state.MAX_LEN);
    615 
    616     size_t pos;
    617     if (memchr(state.ptr1, 0, state.MAX_LEN)) {
    618       pos = strlen(state.ptr1);
    619     } else {
    620       pos = state.MAX_LEN - 1;
    621     }
    622 
    623     memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN);
    624     memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    625 
    626     ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2);
    627     ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 ||
    628                  memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0);
    629   }
    630 }
    631 
    632 TEST(string, strrchr) {
    633   int seek_char = random() & 255;
    634   StringTestState<char> state(SMALL);
    635   for (size_t i = 1; i < state.n; i++) {
    636     for (size_t j = 0; j < POS_ITER; j++) {
    637       state.NewIteration();
    638 
    639       if (~seek_char > 0) {
    640         memset(state.ptr1, ~seek_char, state.len[i]);
    641       } else {
    642         memset(state.ptr1, '\1', state.len[i]);
    643       }
    644       state.ptr1[state.len[i] - 1] = '\0';
    645 
    646       int pos = random() % state.MAX_LEN;
    647       char* expected;
    648       if (pos >= state.len[i] - 1) {
    649         if (seek_char == 0) {
    650           expected = state.ptr1 + state.len[i] - 1;
    651         } else {
    652           expected = NULL;
    653         }
    654       } else {
    655         state.ptr1[pos] = seek_char;
    656         expected = state.ptr1 + pos;
    657       }
    658 
    659       ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
    660     }
    661   }
    662 }
    663 
    664 TEST(string, memchr) {
    665   int seek_char = random() & 255;
    666   StringTestState<char> state(SMALL);
    667   for (size_t i = 0; i < state.n; i++) {
    668     for (size_t j = 0; j < POS_ITER; j++) {
    669       state.NewIteration();
    670 
    671       memset(state.ptr1, ~seek_char, state.len[i]);
    672 
    673       int pos = random() % state.MAX_LEN;
    674       char* expected;
    675       if (pos >= state.len[i]) {
    676         expected = NULL;
    677       } else {
    678         state.ptr1[pos] = seek_char;
    679         expected = state.ptr1 + pos;
    680       }
    681 
    682       ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
    683     }
    684   }
    685 }
    686 
    687 TEST(string, memrchr) {
    688   int seek_char = random() & 255;
    689   StringTestState<char> state(SMALL);
    690   for (size_t i = 0; i < state.n; i++) {
    691     for (size_t j = 0; j < POS_ITER; j++) {
    692       state.NewIteration();
    693 
    694       memset(state.ptr1, ~seek_char, state.len[i]);
    695 
    696       int pos = random() % state.MAX_LEN;
    697       char* expected;
    698       if (pos >= state.len[i]) {
    699         expected = NULL;
    700       } else {
    701         state.ptr1[pos] = seek_char;
    702         expected = state.ptr1 + pos;
    703       }
    704 
    705       ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
    706     }
    707   }
    708 }
    709 
    710 TEST(string, memcmp) {
    711   StringTestState<char> state(SMALL);
    712   for (size_t i = 0; i < state.n; i++) {
    713     for (size_t j = 0; j < POS_ITER; j++) {
    714       state.NewIteration();
    715 
    716       int c1 = random() & 0xff;
    717       int c2 = random() & 0xff;
    718       memset(state.ptr1, c1, state.MAX_LEN);
    719       memset(state.ptr2, c1, state.MAX_LEN);
    720 
    721       int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
    722       state.ptr2[pos] = c2;
    723 
    724       int expected = (static_cast<int>(c1) - static_cast<int>(c2));
    725       int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
    726 
    727       ASSERT_EQ(signum(expected), signum(actual));
    728     }
    729   }
    730 }
    731 
    732 #if defined(__BIONIC__)
    733 extern "C" int __memcmp16(const unsigned short *ptr1, const unsigned short *ptr2, size_t n);
    734 
    735 TEST(string, __memcmp16) {
    736   StringTestState<unsigned short> state(SMALL);
    737 
    738   for (size_t i = 0; i < state.n; i++) {
    739     for (size_t j = 0; j < POS_ITER; j++) {
    740       state.NewIteration();
    741 
    742       unsigned short mask = 0xffff;
    743       unsigned short c1 = rand() & mask;
    744       unsigned short c2 = rand() & mask;
    745 
    746       std::fill(state.ptr1, state.ptr1 + state.MAX_LEN, c1);
    747       std::fill(state.ptr2, state.ptr2 + state.MAX_LEN, c1);
    748 
    749       int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
    750       state.ptr2[pos] = c2;
    751 
    752       int expected = (static_cast<unsigned short>(c1) - static_cast<unsigned short>(c2));
    753       int actual = __memcmp16(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
    754 
    755       ASSERT_EQ(expected, actual);
    756     }
    757   }
    758 }
    759 #endif
    760 
    761 TEST(string, wmemcmp) {
    762   StringTestState<wchar_t> state(SMALL);
    763 
    764   for (size_t i = 0; i < state.n; i++) {
    765     for (size_t j = 0; j < POS_ITER; j++) {
    766       state.NewIteration();
    767 
    768       long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1;
    769       int c1 = rand() & mask;
    770       int c2 = rand() & mask;
    771       wmemset(state.ptr1, c1, state.MAX_LEN);
    772       wmemset(state.ptr2, c1, state.MAX_LEN);
    773 
    774       int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
    775       state.ptr2[pos] = c2;
    776 
    777       int expected = (static_cast<int>(c1) - static_cast<int>(c2));
    778       int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
    779 
    780       ASSERT_EQ(signum(expected), signum(actual));
    781     }
    782   }
    783 }
    784 
    785 TEST(string, memcpy) {
    786   StringTestState<char> state(LARGE);
    787   int rand = random() & 255;
    788   for (size_t i = 0; i < state.n - 1; i++) {
    789     for (size_t j = 0; j < POS_ITER; j++) {
    790       state.NewIteration();
    791 
    792       size_t pos = random() % (state.MAX_LEN - state.len[i]);
    793 
    794       memset(state.ptr1, rand, state.len[i]);
    795       memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
    796 
    797       memset(state.ptr2, rand, state.len[i]);
    798       memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
    799       memset(state.ptr2 + pos, '\0', state.len[i]);
    800 
    801       ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
    802       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
    803     }
    804   }
    805 }
    806 
    807 TEST(string, memset) {
    808   StringTestState<char> state(LARGE);
    809   char ch = random () & 255;
    810   for (size_t i = 0; i < state.n - 1; i++) {
    811     for (size_t j = 0; j < POS_ITER; j++) {
    812       state.NewIteration();
    813 
    814       memset(state.ptr1, ~ch, state.MAX_LEN);
    815       memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
    816 
    817       size_t pos = random () % (state.MAX_LEN - state.len[i]);
    818       for (size_t k = pos; k < pos + state.len[i]; k++) {
    819         state.ptr1[k] = ch;
    820       }
    821 
    822       ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
    823 
    824       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
    825     }
    826   }
    827 }
    828 
    829 TEST(string, memmove) {
    830   StringTestState<char> state(LARGE);
    831   for (size_t i = 0; i < state.n - 1; i++) {
    832     for (size_t j = 0; j < POS_ITER; j++) {
    833       state.NewIteration();
    834 
    835       memset(state.ptr1, random() & 255, 2 * state.MAX_LEN);
    836 
    837       size_t pos = random() % (state.MAX_LEN - state.len[i]);
    838 
    839       memset(state.ptr1, random() & 255, state.len[i]);
    840       memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
    841       memcpy(state.ptr, state.ptr1, state.len[i]);
    842       memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
    843 
    844       ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
    845       ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
    846     }
    847   }
    848 }
    849 
    850 TEST(string, bcopy) {
    851   StringTestState<char> state(LARGE);
    852   for (size_t i = 0; i < state.n; i++) {
    853     for (size_t j = 0; j < POS_ITER; j++) {
    854       state.NewIteration();
    855 
    856       memset(state.ptr1, random() & 255, state.MAX_LEN);
    857       memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN);
    858       memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
    859 
    860       size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
    861       memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
    862 
    863       bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
    864       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
    865     }
    866   }
    867 }
    868 
    869 TEST(string, bzero) {
    870   StringTestState<char> state(LARGE);
    871   for (size_t j = 0; j < ITER; j++) {
    872     state.NewIteration();
    873 
    874     memset(state.ptr1, random() & 255, state.MAX_LEN);
    875 
    876     size_t start = random() % state.MAX_LEN;
    877     size_t end = start + random() % (state.MAX_LEN - start);
    878 
    879     memcpy(state.ptr2, state.ptr1, start);
    880     memset(state.ptr2 + start, '\0', end - start);
    881     memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
    882 
    883     bzero(state.ptr1 + start, end - start);
    884 
    885     ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
    886   }
    887 }
    888