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 #define _GNU_SOURCE 1
     18 
     19 #include <string.h>
     20 
     21 #include <errno.h>
     22 #include <gtest/gtest.h>
     23 #include <malloc.h>
     24 #include <math.h>
     25 #include <stdint.h>
     26 
     27 #include <algorithm>
     28 #include <vector>
     29 
     30 #include "buffer_tests.h"
     31 
     32 #if defined(NOFORTIFY)
     33 #define STRING_TEST string_nofortify
     34 #else
     35 #define STRING_TEST string
     36 #endif
     37 
     38 #if defined(__BIONIC__)
     39 #define STRLCPY_SUPPORTED
     40 #define STRLCAT_SUPPORTED
     41 #endif
     42 
     43 constexpr auto KB = 1024;
     44 constexpr auto SMALL = 1 * KB;
     45 constexpr auto MEDIUM = 4 * KB;
     46 constexpr auto LARGE = 64 * KB;
     47 
     48 static int signum(int i) {
     49   if (i < 0) {
     50     return -1;
     51   } else if (i > 0) {
     52     return 1;
     53   }
     54   return 0;
     55 }
     56 
     57 TEST(STRING_TEST, strerror) {
     58   // Valid.
     59   ASSERT_STREQ("Success", strerror(0));
     60   ASSERT_STREQ("Operation not permitted", strerror(1));
     61 
     62   // Invalid.
     63   ASSERT_STREQ("Unknown error -1", strerror(-1));
     64   ASSERT_STREQ("Unknown error 1234", strerror(1234));
     65 }
     66 
     67 #if defined(__BIONIC__)
     68 static void* ConcurrentStrErrorFn(void*) {
     69   bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
     70   return reinterpret_cast<void*>(equal);
     71 }
     72 #endif // __BIONIC__
     73 
     74 // glibc's strerror isn't thread safe, only its strsignal.
     75 TEST(STRING_TEST, strerror_concurrent) {
     76 #if defined(__BIONIC__)
     77   const char* strerror1001 = strerror(1001);
     78   ASSERT_STREQ("Unknown error 1001", strerror1001);
     79 
     80   pthread_t t;
     81   ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL));
     82   void* result;
     83   ASSERT_EQ(0, pthread_join(t, &result));
     84   ASSERT_TRUE(static_cast<bool>(result));
     85 
     86   ASSERT_STREQ("Unknown error 1001", strerror1001);
     87 #else // __BIONIC__
     88   GTEST_LOG_(INFO) << "Skipping test, requires a thread safe strerror.";
     89 #endif // __BIONIC__
     90 }
     91 
     92 TEST(STRING_TEST, gnu_strerror_r) {
     93   char buf[256];
     94 
     95   // Note that glibc doesn't necessarily write into the buffer.
     96 
     97   // Valid.
     98   ASSERT_STREQ("Success", strerror_r(0, buf, sizeof(buf)));
     99 #if defined(__BIONIC__)
    100   ASSERT_STREQ("Success", buf);
    101 #endif
    102   ASSERT_STREQ("Operation not permitted", strerror_r(1, buf, sizeof(buf)));
    103 #if defined(__BIONIC__)
    104   ASSERT_STREQ("Operation not permitted", buf);
    105 #endif
    106 
    107   // Invalid.
    108   ASSERT_STREQ("Unknown error -1", strerror_r(-1, buf, sizeof(buf)));
    109   ASSERT_STREQ("Unknown error -1", buf);
    110   ASSERT_STREQ("Unknown error 1234", strerror_r(1234, buf, sizeof(buf)));
    111   ASSERT_STREQ("Unknown error 1234", buf);
    112 
    113   // Buffer too small.
    114   errno = 0;
    115   memset(buf, 0, sizeof(buf));
    116   ASSERT_EQ(buf, strerror_r(4567, buf, 2));
    117   ASSERT_STREQ("U", buf);
    118   // The GNU strerror_r doesn't set errno (the POSIX one sets it to ERANGE).
    119   ASSERT_EQ(0, errno);
    120 }
    121 
    122 TEST(STRING_TEST, strsignal) {
    123   // A regular signal.
    124   ASSERT_STREQ("Hangup", strsignal(1));
    125 
    126   // A real-time signal.
    127   ASSERT_STREQ("Real-time signal 14", strsignal(SIGRTMIN + 14));
    128   // One of the signals the C library keeps to itself.
    129   ASSERT_STREQ("Unknown signal 32", strsignal(__SIGRTMIN));
    130 
    131   // Errors.
    132   ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
    133   ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small.
    134   ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large.
    135 }
    136 
    137 static void* ConcurrentStrSignalFn(void*) {
    138   bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
    139   return reinterpret_cast<void*>(equal);
    140 }
    141 
    142 TEST(STRING_TEST, strsignal_concurrent) {
    143   const char* strsignal1001 = strsignal(1001);
    144   ASSERT_STREQ("Unknown signal 1001", strsignal1001);
    145 
    146   pthread_t t;
    147   ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL));
    148   void* result;
    149   ASSERT_EQ(0, pthread_join(t, &result));
    150   ASSERT_TRUE(static_cast<bool>(result));
    151 
    152   ASSERT_STREQ("Unknown signal 1001", strsignal1001);
    153 }
    154 
    155 // TODO: where did this number come from?
    156 #define ITER        500
    157 
    158 // For every length we want to test, vary and change alignment
    159 // of allocated memory, fill it with some values, calculate
    160 // expected result and then run function and compare what we got.
    161 // These tests contributed by Intel Corporation.
    162 // TODO: make these tests more intention-revealing and less random.
    163 template<class Character>
    164 class StringTestState {
    165  public:
    166   explicit StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN), align1_index_(0), align2_index_(0) {
    167     int max_alignment = 64;
    168 
    169     // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
    170     glob_ptr = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
    171     glob_ptr1 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
    172     glob_ptr2 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
    173 
    174     InitLenArray();
    175 
    176     srandom(1234);
    177   }
    178 
    179   ~StringTestState() {
    180     free(glob_ptr);
    181     free(glob_ptr1);
    182     free(glob_ptr2);
    183   }
    184 
    185   void BeginIterations() {
    186     align1_index_ = 0;
    187     align2_index_ = 0;
    188 
    189     ResetPointers();
    190   }
    191 
    192   bool HasNextIteration() {
    193     return (align1_index_ != (alignments_size - 1) || align2_index_ != (alignments_size - 1));
    194   }
    195 
    196   void NextIteration() {
    197     if (align1_index_ == (alignments_size - 1) && align2_index_ == (alignments_size - 1)) {
    198       return;
    199     }
    200 
    201     if (align1_index_ == (alignments_size - 1)) {
    202       align1_index_ = 0;
    203       align2_index_++;
    204     } else {
    205       align1_index_++;
    206     }
    207 
    208     ResetPointers();
    209   }
    210 
    211   const size_t MAX_LEN;
    212   Character *ptr, *ptr1, *ptr2;
    213   size_t n;
    214   size_t len[ITER + 1];
    215 
    216  private:
    217   static size_t alignments[];
    218   static size_t alignments_size;
    219   Character *glob_ptr, *glob_ptr1, *glob_ptr2;
    220   size_t align1_index_, align2_index_;
    221 
    222   // Calculate input lengths and fill state.len with them.
    223   // Test small lengths with more density than big ones. Manually push
    224   // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
    225   // Return number of lengths to test.
    226   void InitLenArray() {
    227     n = 0;
    228     len[n++] = 0;
    229     for (size_t i = 1; i < ITER; ++i) {
    230       size_t l = static_cast<size_t>(exp(log(static_cast<double>(MAX_LEN)) * i / ITER));
    231       if (l != len[n - 1]) {
    232         len[n++] = l;
    233       }
    234     }
    235     len[n++] = MAX_LEN;
    236   }
    237 
    238   void ResetPointers() {
    239     if (align1_index_ == alignments_size || align2_index_ == alignments_size) {
    240       ptr = ptr1 = ptr2 = nullptr;
    241     } else {
    242       ptr = glob_ptr + alignments[align1_index_];
    243       ptr1 = glob_ptr1 + alignments[align1_index_];
    244       ptr2 = glob_ptr2 + alignments[align2_index_];
    245     }
    246   }
    247 };
    248 
    249 template<class Character>
    250 size_t StringTestState<Character>::alignments[] = { 24, 32, 16, 48, 0, 1, 2, 3, 4, 5, 6, 7, 11 };
    251 
    252 template<class Character>
    253 size_t StringTestState<Character>::alignments_size = sizeof(alignments)/sizeof(size_t);
    254 
    255 TEST(STRING_TEST, strcat) {
    256   StringTestState<char> state(SMALL);
    257   for (size_t i = 1; i < state.n; i++) {
    258     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    259       memset(state.ptr2, '\2', state.MAX_LEN);
    260       state.ptr2[state.MAX_LEN - 1] = '\0';
    261       memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
    262 
    263       memset(state.ptr1, 'L', state.len[i]);
    264       state.ptr1[random() % state.len[i]] = '\0';
    265       state.ptr1[state.len[i] - 1] = '\0';
    266 
    267       strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
    268 
    269       EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
    270       EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
    271     }
    272   }
    273 }
    274 
    275 // one byte target with "\0" source
    276 TEST(STRING_TEST, strcpy2) {
    277   char buf[1];
    278   char* orig = strdup("");
    279   ASSERT_EQ(buf, strcpy(buf, orig));
    280   ASSERT_EQ('\0', buf[0]);
    281   free(orig);
    282 }
    283 
    284 // multibyte target where we under fill target
    285 TEST(STRING_TEST, strcpy3) {
    286   char buf[10];
    287   char* orig = strdup("12345");
    288   memset(buf, 'A', sizeof(buf));
    289   ASSERT_EQ(buf, strcpy(buf, orig));
    290   ASSERT_STREQ("12345", buf);
    291   ASSERT_EQ('A',  buf[6]);
    292   ASSERT_EQ('A',  buf[7]);
    293   ASSERT_EQ('A',  buf[8]);
    294   ASSERT_EQ('A',  buf[9]);
    295   free(orig);
    296 }
    297 
    298 // multibyte target where we fill target exactly
    299 TEST(STRING_TEST, strcpy4) {
    300   char buf[10];
    301   char* orig = strdup("123456789");
    302   memset(buf, 'A', sizeof(buf));
    303   ASSERT_EQ(buf, strcpy(buf, orig));
    304   ASSERT_STREQ("123456789", buf);
    305   free(orig);
    306 }
    307 
    308 // one byte target with "\0" source
    309 TEST(STRING_TEST, stpcpy2) {
    310   char buf[1];
    311   char* orig = strdup("");
    312   ASSERT_EQ(buf, stpcpy(buf, orig));
    313   ASSERT_EQ('\0', buf[0]);
    314   free(orig);
    315 }
    316 
    317 // multibyte target where we under fill target
    318 TEST(STRING_TEST, stpcpy3) {
    319   char buf[10];
    320   char* orig = strdup("12345");
    321   memset(buf, 'A', sizeof(buf));
    322   ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
    323   ASSERT_STREQ("12345", buf);
    324   ASSERT_EQ('A',  buf[6]);
    325   ASSERT_EQ('A',  buf[7]);
    326   ASSERT_EQ('A',  buf[8]);
    327   ASSERT_EQ('A',  buf[9]);
    328   free(orig);
    329 }
    330 
    331 // multibyte target where we fill target exactly
    332 TEST(STRING_TEST, stpcpy4) {
    333   char buf[10];
    334   char* orig = strdup("123456789");
    335   memset(buf, 'A', sizeof(buf));
    336   ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
    337   ASSERT_STREQ("123456789", buf);
    338   free(orig);
    339 }
    340 
    341 TEST(STRING_TEST, strcat2) {
    342   char buf[10];
    343   memset(buf, 'A', sizeof(buf));
    344   buf[0] = 'a';
    345   buf[1] = '\0';
    346   char* res = strcat(buf, "01234");
    347   ASSERT_EQ(buf, res);
    348   ASSERT_STREQ("a01234", buf);
    349   ASSERT_EQ('A',  buf[7]);
    350   ASSERT_EQ('A',  buf[8]);
    351   ASSERT_EQ('A',  buf[9]);
    352 }
    353 
    354 TEST(STRING_TEST, strcat3) {
    355   char buf[10];
    356   memset(buf, 'A', sizeof(buf));
    357   buf[0] = 'a';
    358   buf[1] = '\0';
    359   char* res = strcat(buf, "01234567");
    360   ASSERT_EQ(buf, res);
    361   ASSERT_STREQ("a01234567", buf);
    362 }
    363 
    364 TEST(STRING_TEST, strncat2) {
    365   char buf[10];
    366   memset(buf, 'A', sizeof(buf));
    367   buf[0] = 'a';
    368   buf[1] = '\0';
    369   char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1);
    370   ASSERT_EQ(buf, res);
    371   ASSERT_STREQ("a01234", buf);
    372   ASSERT_EQ('A',  buf[7]);
    373   ASSERT_EQ('A',  buf[8]);
    374   ASSERT_EQ('A',  buf[9]);
    375 }
    376 
    377 TEST(STRING_TEST, strncat3) {
    378   char buf[10];
    379   memset(buf, 'A', sizeof(buf));
    380   buf[0] = 'a';
    381   buf[1] = '\0';
    382   char* res = strncat(buf, "0123456789", 5);
    383   ASSERT_EQ(buf, res);
    384   ASSERT_STREQ("a01234", buf);
    385   ASSERT_EQ('A',  buf[7]);
    386   ASSERT_EQ('A',  buf[8]);
    387   ASSERT_EQ('A',  buf[9]);
    388 }
    389 
    390 TEST(STRING_TEST, strncat4) {
    391   char buf[10];
    392   memset(buf, 'A', sizeof(buf));
    393   buf[0] = 'a';
    394   buf[1] = '\0';
    395   char* res = strncat(buf, "01234567", 8);
    396   ASSERT_EQ(buf, res);
    397   ASSERT_STREQ("a01234567", buf);
    398 }
    399 
    400 TEST(STRING_TEST, strncat5) {
    401   char buf[10];
    402   memset(buf, 'A', sizeof(buf));
    403   buf[0] = 'a';
    404   buf[1] = '\0';
    405   char* res = strncat(buf, "01234567", 9);
    406   ASSERT_EQ(buf, res);
    407   ASSERT_STREQ("a01234567", buf);
    408 }
    409 
    410 TEST(STRING_TEST, strchr_with_0) {
    411   char buf[10];
    412   const char* s = "01234";
    413   memcpy(buf, s, strlen(s) + 1);
    414   EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
    415 }
    416 
    417 TEST(STRING_TEST, strchr_multiple) {
    418   char str[128];
    419   memset(str, 'a', sizeof(str) - 1);
    420   str[sizeof(str)-1] = '\0';
    421 
    422   // Verify that strchr finds the first occurrence of 'a' in a string
    423   // filled with 'a' characters. Iterate over the string putting
    424   // non 'a' characters at the front of the string during each iteration
    425   // and continue to verify that strchr can find the first occurrence
    426   // properly. The idea is to cover all possible alignments of the location
    427   // of the first occurrence of the 'a' character and which includes
    428   // other 'a' characters close by.
    429   for (size_t i = 0; i < sizeof(str) - 1; i++) {
    430     EXPECT_EQ(&str[i], strchr(str, 'a'));
    431     str[i] = 'b';
    432   }
    433 }
    434 
    435 TEST(STRING_TEST, strchr) {
    436   int seek_char = 'R';
    437 
    438   StringTestState<char> state(SMALL);
    439   for (size_t i = 1; i < state.n; i++) {
    440     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    441       if (~seek_char > 0) {
    442         memset(state.ptr1, ~seek_char, state.len[i]);
    443       } else {
    444         memset(state.ptr1, '\1', state.len[i]);
    445       }
    446       state.ptr1[state.len[i] - 1] = '\0';
    447 
    448       size_t pos = random() % state.MAX_LEN;
    449       char* expected;
    450       if (pos >= state.len[i] - 1) {
    451         if (seek_char == 0) {
    452           expected = state.ptr1 + state.len[i] - 1;
    453         } else {
    454           expected = NULL;
    455         }
    456       } else {
    457         state.ptr1[pos] = seek_char;
    458         expected = state.ptr1 + pos;
    459       }
    460 
    461       ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
    462     }
    463   }
    464 }
    465 
    466 TEST(STRING_TEST, strchrnul) {
    467   const char* s = "01234222";
    468   EXPECT_TRUE(strchrnul(s, '2') == &s[2]);
    469   EXPECT_TRUE(strchrnul(s, '8') == (s + strlen(s)));
    470   EXPECT_TRUE(strchrnul(s, '\0') == (s + strlen(s)));
    471 }
    472 
    473 TEST(STRING_TEST, strcmp) {
    474   StringTestState<char> state(SMALL);
    475   for (size_t i = 1; i < state.n; i++) {
    476     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    477       memset(state.ptr1, 'v', state.MAX_LEN);
    478       memset(state.ptr2, 'n', state.MAX_LEN);
    479       state.ptr1[state.len[i] - 1] = '\0';
    480       state.ptr2[state.len[i] - 1] = '\0';
    481 
    482       size_t pos = 1 + (random() % (state.MAX_LEN - 1));
    483       int actual;
    484       int expected;
    485       if (pos >= state.len[i] - 1) {
    486         memcpy(state.ptr1, state.ptr2, state.len[i]);
    487         expected = 0;
    488         actual = strcmp(state.ptr1, state.ptr2);
    489       } else {
    490         memcpy(state.ptr1, state.ptr2, pos);
    491         if (state.ptr1[pos] > state.ptr2[pos]) {
    492           expected = 1;
    493         } else if (state.ptr1[pos] == state.ptr2[pos]) {
    494           state.ptr1[pos + 1] = '\0';
    495           state.ptr2[pos + 1] = '\0';
    496           expected = 0;
    497         } else {
    498           expected = -1;
    499         }
    500         actual = strcmp(state.ptr1, state.ptr2);
    501       }
    502 
    503       ASSERT_EQ(expected, signum(actual));
    504     }
    505   }
    506 }
    507 
    508 TEST(STRING_TEST, stpcpy) {
    509   StringTestState<char> state(SMALL);
    510   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    511     size_t pos = random() % state.MAX_LEN;
    512 
    513     memset(state.ptr1, '\2', pos);
    514     state.ptr1[pos] = '\0';
    515     state.ptr1[state.MAX_LEN - 1] = '\0';
    516 
    517     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    518 
    519     memset(state.ptr2, '\1', state.MAX_LEN);
    520     state.ptr2[state.MAX_LEN - 1] = '\0';
    521 
    522     memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
    523     memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    524     state.ptr[2 * state.MAX_LEN - 1] = '\0';
    525 
    526     ASSERT_TRUE(stpcpy(state.ptr2, state.ptr1) == state.ptr2 + strlen(state.ptr1));
    527     ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
    528                  (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
    529   }
    530 }
    531 
    532 TEST(STRING_TEST, strcpy) {
    533   StringTestState<char> state(SMALL);
    534   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    535     size_t pos = random() % state.MAX_LEN;
    536 
    537     memset(state.ptr1, '\2', pos);
    538     state.ptr1[pos] = '\0';
    539     state.ptr1[state.MAX_LEN - 1] = '\0';
    540 
    541     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    542 
    543     memset(state.ptr2, '\1', state.MAX_LEN);
    544     state.ptr2[state.MAX_LEN - 1] = '\0';
    545 
    546     memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
    547     memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    548     state.ptr[2 * state.MAX_LEN - 1] = '\0';
    549 
    550     ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
    551     ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
    552                  (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
    553   }
    554 }
    555 
    556 TEST(STRING_TEST, strlcat) {
    557 #if defined(STRLCAT_SUPPORTED)
    558   StringTestState<char> state(SMALL);
    559   for (size_t i = 0; i < state.n; i++) {
    560     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    561       memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
    562       state.ptr2[state.MAX_LEN - 1] = '\0';
    563       memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
    564 
    565       size_t pos = random() % state.MAX_LEN;
    566       memset(state.ptr1, '\3', pos);
    567       state.ptr1[pos] = '\0';
    568       if (pos < state.len[i]) {
    569         memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
    570       } else {
    571         memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
    572         state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
    573       }
    574 
    575       strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
    576 
    577       ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
    578     }
    579   }
    580 #else
    581   GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
    582 #endif
    583 }
    584 
    585 TEST(STRING_TEST, strlcpy) {
    586 #if defined(STRLCPY_SUPPORTED)
    587   StringTestState<char> state(SMALL);
    588   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    589     int rand = 'O';
    590     memset(state.ptr1, rand, state.MAX_LEN);
    591 
    592     size_t pos = random() % state.MAX_LEN;
    593     if (pos < state.MAX_LEN) {
    594       state.ptr1[pos] = '\0';
    595     }
    596     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    597 
    598     memset(state.ptr2, 'I', state.MAX_LEN);
    599     memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
    600 
    601     if (pos > state.MAX_LEN - 1) {
    602       memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
    603       state.ptr[2 * state.MAX_LEN - 1] = '\0';
    604     } else {
    605       memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
    606     }
    607 
    608     ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
    609     ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
    610                  (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
    611   }
    612 #else
    613   GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
    614 #endif
    615 }
    616 
    617 TEST(STRING_TEST, strncat) {
    618   StringTestState<char> state(SMALL);
    619   for (size_t i = 1; i < state.n; i++) {
    620     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    621       memset(state.ptr2, '\2', state.MAX_LEN);
    622       state.ptr2[state.MAX_LEN - 1] = '\0';
    623       memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
    624 
    625       memset(state.ptr1, 'I', state.len[i]);
    626       state.ptr1[random() % state.len[i]] = '\0';
    627       state.ptr1[state.len[i] - 1] = '\0';
    628 
    629       size_t pos = strlen(state.ptr1);
    630 
    631       size_t actual = random() % state.len[i];
    632       strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
    633       state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
    634 
    635       ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
    636       ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
    637     }
    638   }
    639 }
    640 
    641 TEST(STRING_TEST, strncmp) {
    642   StringTestState<char> state(SMALL);
    643   for (size_t i = 1; i < state.n; i++) {
    644     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    645       memset(state.ptr1, 'v', state.MAX_LEN);
    646       memset(state.ptr2, 'n', state.MAX_LEN);
    647       state.ptr1[state.len[i] - 1] = '\0';
    648       state.ptr2[state.len[i] - 1] = '\0';
    649 
    650       size_t pos = 1 + (random() % (state.MAX_LEN - 1));
    651       int actual;
    652       int expected;
    653       if (pos >= state.len[i] - 1) {
    654         memcpy(state.ptr1, state.ptr2, state.len[i]);
    655         expected = 0;
    656         actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
    657       } else {
    658         memcpy(state.ptr1, state.ptr2, pos);
    659         if (state.ptr1[pos] > state.ptr2[pos]) {
    660           expected = 1;
    661         } else if (state.ptr1[pos] == state.ptr2[pos]) {
    662           state.ptr1[pos + 1] = '\0';
    663           state.ptr2[pos + 1] = '\0';
    664           expected = 0;
    665         } else {
    666           expected = -1;
    667         }
    668         actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
    669       }
    670 
    671       ASSERT_EQ(expected, signum(actual));
    672     }
    673   }
    674 }
    675 
    676 TEST(STRING_TEST, stpncpy) {
    677   StringTestState<char> state(SMALL);
    678   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    679     memset(state.ptr1, 'J', state.MAX_LEN);
    680     // Choose a random size for our src buffer.
    681     size_t ptr1_len = random() % state.MAX_LEN;
    682     state.ptr1[ptr1_len] = '\0';
    683     // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
    684     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    685     // Init ptr2 to a set value.
    686     memset(state.ptr2, '\1', state.MAX_LEN);
    687 
    688     // Choose a random amount of data to copy.
    689     size_t copy_len = random() % state.MAX_LEN;
    690 
    691     // Set the second half of ptr to the expected pattern in ptr2.
    692     memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
    693     memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
    694     size_t expected_end;
    695     if (copy_len > ptr1_len) {
    696       memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
    697       expected_end = ptr1_len;
    698     } else {
    699       expected_end = copy_len;
    700     }
    701 
    702     ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
    703 
    704     // Verify ptr1 was not modified.
    705     ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
    706     // Verify ptr2 contains the expected data.
    707     ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
    708   }
    709 }
    710 
    711 TEST(STRING_TEST, strncpy) {
    712   StringTestState<char> state(SMALL);
    713   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    714     // Choose a random value to fill the string, except \0 (string terminator),
    715     // or \1 (guarantees it's different from anything in ptr2).
    716     memset(state.ptr1, 'K', state.MAX_LEN);
    717     // Choose a random size for our src buffer.
    718     size_t ptr1_len = random() % state.MAX_LEN;
    719     state.ptr1[ptr1_len] = '\0';
    720     // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
    721     memcpy(state.ptr, state.ptr1, state.MAX_LEN);
    722     // Init ptr2 to a set value.
    723     memset(state.ptr2, '\1', state.MAX_LEN);
    724 
    725     // Choose a random amount of data to copy.
    726     size_t copy_len = random() % state.MAX_LEN;
    727 
    728     // Set the second half of ptr to the expected pattern in ptr2.
    729     memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
    730     memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
    731     size_t expected_end;
    732     if (copy_len > ptr1_len) {
    733       memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
    734       expected_end = ptr1_len;
    735     } else {
    736       expected_end = copy_len;
    737     }
    738 
    739     ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
    740 
    741     // Verify ptr1 was not modified.
    742     ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
    743     // Verify ptr2 contains the expected data.
    744     ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
    745   }
    746 }
    747 
    748 TEST(STRING_TEST, strrchr) {
    749   int seek_char = 'M';
    750   StringTestState<char> state(SMALL);
    751   for (size_t i = 1; i < state.n; i++) {
    752     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    753       if (~seek_char > 0) {
    754         memset(state.ptr1, ~seek_char, state.len[i]);
    755       } else {
    756         memset(state.ptr1, '\1', state.len[i]);
    757       }
    758       state.ptr1[state.len[i] - 1] = '\0';
    759 
    760       size_t pos = random() % state.MAX_LEN;
    761       char* expected;
    762       if (pos >= state.len[i] - 1) {
    763         if (seek_char == 0) {
    764           expected = state.ptr1 + state.len[i] - 1;
    765         } else {
    766           expected = NULL;
    767         }
    768       } else {
    769         state.ptr1[pos] = seek_char;
    770         expected = state.ptr1 + pos;
    771       }
    772 
    773       ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
    774     }
    775   }
    776 }
    777 
    778 TEST(STRING_TEST, memchr) {
    779   int seek_char = 'N';
    780   StringTestState<char> state(SMALL);
    781   for (size_t i = 0; i < state.n; i++) {
    782     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    783       memset(state.ptr1, ~seek_char, state.len[i]);
    784 
    785       size_t pos = random() % state.MAX_LEN;
    786       char* expected;
    787       if (pos >= state.len[i]) {
    788         expected = NULL;
    789       } else {
    790         state.ptr1[pos] = seek_char;
    791         expected = state.ptr1 + pos;
    792       }
    793 
    794       ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
    795     }
    796   }
    797 }
    798 
    799 TEST(STRING_TEST, memchr_zero) {
    800   uint8_t* buffer;
    801   ASSERT_EQ(0, posix_memalign(reinterpret_cast<void**>(&buffer), 64, 64));
    802   memset(buffer, 10, 64);
    803   ASSERT_TRUE(NULL == memchr(buffer, 5, 0));
    804   ASSERT_TRUE(NULL == memchr(buffer, 10, 0));
    805 }
    806 
    807 TEST(STRING_TEST, memrchr) {
    808   int seek_char = 'P';
    809   StringTestState<char> state(SMALL);
    810   for (size_t i = 0; i < state.n; i++) {
    811     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    812       memset(state.ptr1, ~seek_char, state.len[i]);
    813 
    814       size_t pos = random() % state.MAX_LEN;
    815       char* expected;
    816       if (pos >= state.len[i]) {
    817         expected = NULL;
    818       } else {
    819         state.ptr1[pos] = seek_char;
    820         expected = state.ptr1 + pos;
    821       }
    822 
    823       ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
    824     }
    825   }
    826 }
    827 
    828 TEST(STRING_TEST, memcmp) {
    829   StringTestState<char> state(SMALL);
    830   for (size_t i = 0; i < state.n; i++) {
    831     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    832       int c1 = 'A';
    833       int c2 = 'N';
    834       memset(state.ptr1, c1, state.MAX_LEN);
    835       memset(state.ptr2, c1, state.MAX_LEN);
    836 
    837       int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
    838       state.ptr2[pos] = c2;
    839 
    840       int expected = (static_cast<int>(c1) - static_cast<int>(c2));
    841       int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
    842 
    843       ASSERT_EQ(signum(expected), signum(actual));
    844     }
    845   }
    846 }
    847 
    848 TEST(STRING_TEST, wmemcmp) {
    849   StringTestState<wchar_t> state(SMALL);
    850 
    851   for (size_t i = 0; i < state.n; i++) {
    852     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    853       long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1;
    854       int c1 = rand() & mask;
    855       int c2 = rand() & mask;
    856       wmemset(state.ptr1, c1, state.MAX_LEN);
    857       wmemset(state.ptr2, c1, state.MAX_LEN);
    858 
    859       int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
    860       state.ptr2[pos] = c2;
    861 
    862       int expected = (static_cast<int>(c1) - static_cast<int>(c2));
    863       int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
    864 
    865       ASSERT_EQ(signum(expected), signum(actual));
    866     }
    867   }
    868 }
    869 
    870 TEST(STRING_TEST, memcpy) {
    871   StringTestState<char> state(LARGE);
    872   int rand = 4;
    873   for (size_t i = 0; i < state.n - 1; i++) {
    874     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    875       size_t pos = random() % (state.MAX_LEN - state.len[i]);
    876 
    877       memset(state.ptr1, rand, state.len[i]);
    878       memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
    879 
    880       memset(state.ptr2, rand, state.len[i]);
    881       memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
    882       memset(state.ptr2 + pos, '\0', state.len[i]);
    883 
    884       ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
    885       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
    886     }
    887   }
    888 }
    889 
    890 TEST(STRING_TEST, memset) {
    891   StringTestState<char> state(LARGE);
    892   char ch = 'P';
    893   for (size_t i = 0; i < state.n - 1; i++) {
    894     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    895       memset(state.ptr1, ~ch, state.MAX_LEN);
    896       memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
    897 
    898       size_t pos = random () % (state.MAX_LEN - state.len[i]);
    899       for (size_t k = pos; k < pos + state.len[i]; k++) {
    900         state.ptr1[k] = ch;
    901       }
    902 
    903       ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
    904 
    905       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
    906     }
    907   }
    908 }
    909 
    910 TEST(STRING_TEST, memmove) {
    911   StringTestState<char> state(LARGE);
    912   for (size_t i = 0; i < state.n - 1; i++) {
    913     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
    914       memset(state.ptr1, 'Q', 2 * state.MAX_LEN);
    915 
    916       size_t pos = random() % (state.MAX_LEN - state.len[i]);
    917 
    918       memset(state.ptr1, 'R', state.len[i]);
    919       memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
    920       memcpy(state.ptr, state.ptr1, state.len[i]);
    921       memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
    922 
    923       ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
    924       ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
    925     }
    926   }
    927 }
    928 
    929 TEST(STRING_TEST, memmove_cache_size) {
    930   size_t len = 600000;
    931   int max_alignment = 31;
    932   int alignments[] = {0, 5, 11, 29, 30};
    933   char* ptr = reinterpret_cast<char*>(malloc(sizeof(char) * len));
    934   char* ptr1 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len));
    935   char* glob_ptr2 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len + max_alignment));
    936   size_t pos = 64;
    937 
    938   ASSERT_TRUE(ptr != NULL);
    939   ASSERT_TRUE(ptr1 != NULL);
    940   ASSERT_TRUE(glob_ptr2 != NULL);
    941 
    942   for (int i = 0; i < 5; i++) {
    943     char* ptr2 = glob_ptr2 + alignments[i];
    944     memset(ptr1, 'S', 2 * len);
    945     memset(ptr1, 'T', len);
    946     memcpy(ptr2, ptr1, 2 * len);
    947     memcpy(ptr, ptr1, len);
    948     memcpy(ptr1 + pos, ptr, len);
    949 
    950     ASSERT_TRUE(memmove(ptr2 + pos, ptr, len) == ptr2 + pos);
    951     ASSERT_EQ(0, memcmp(ptr2, ptr1, 2 * len));
    952   }
    953   free(ptr);
    954   free(ptr1);
    955   free(glob_ptr2);
    956 }
    957 
    958 static void verify_memmove(char* src_copy, char* dst, char* src, size_t size) {
    959   memset(dst, 0, size);
    960   memcpy(src, src_copy, size);
    961   ASSERT_EQ(dst, memmove(dst, src, size));
    962   ASSERT_EQ(0, memcmp(dst, src_copy, size));
    963 }
    964 
    965 #define MEMMOVE_DATA_SIZE (1024*1024*3)
    966 
    967 TEST(STRING_TEST, memmove_check) {
    968   char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
    969   ASSERT_TRUE(buffer != NULL);
    970 
    971   char* src_data = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
    972   ASSERT_TRUE(src_data != NULL);
    973   // Initialize to a known pattern to copy into src for each test and
    974   // to compare dst against.
    975   for (size_t i = 0; i < MEMMOVE_DATA_SIZE; i++) {
    976     src_data[i] = (i + 1) % 255;
    977   }
    978 
    979   // Check all different dst offsets between 0 and 127 inclusive.
    980   char* src = buffer;
    981   for (size_t i = 0; i < 127; i++) {
    982     char* dst = buffer + 256 + i;
    983     // Small copy.
    984     verify_memmove(src_data, dst, src, 1024);
    985 
    986     // Medium copy.
    987     verify_memmove(src_data, dst, src, 64 * 1024);
    988 
    989     // Medium copy.
    990     verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
    991   }
    992 
    993   // Check all leftover size offsets between 1 and 127 inclusive.
    994   char* dst = buffer + 256;
    995   src = buffer;
    996   for (size_t size = 1; size < 127; size++) {
    997     // Small copy.
    998     verify_memmove(src_data, dst, src, 1024);
    999 
   1000     // Medium copy.
   1001     verify_memmove(src_data, dst, src, 64 * 1024);
   1002 
   1003     // Large copy.
   1004     verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
   1005   }
   1006 }
   1007 
   1008 TEST(STRING_TEST, bcopy) {
   1009   StringTestState<char> state(LARGE);
   1010   for (size_t i = 0; i < state.n; i++) {
   1011     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
   1012       memset(state.ptr1, '4', state.MAX_LEN);
   1013       memset(state.ptr1 + state.MAX_LEN, 'a', state.MAX_LEN);
   1014       memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
   1015 
   1016       size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
   1017       memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
   1018 
   1019       bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
   1020       ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
   1021     }
   1022   }
   1023 }
   1024 
   1025 TEST(STRING_TEST, bzero) {
   1026   StringTestState<char> state(LARGE);
   1027   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
   1028     memset(state.ptr1, 'R', state.MAX_LEN);
   1029 
   1030     size_t start = random() % state.MAX_LEN;
   1031     size_t end = start + random() % (state.MAX_LEN - start);
   1032 
   1033     memcpy(state.ptr2, state.ptr1, start);
   1034     memset(state.ptr2 + start, '\0', end - start);
   1035     memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
   1036 
   1037     bzero(state.ptr1 + start, end - start);
   1038 
   1039     ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
   1040   }
   1041 }
   1042 
   1043 static void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
   1044   memset(src, (len % 255) + 1, len);
   1045   memset(dst, 0, len);
   1046 
   1047   ASSERT_EQ(dst, memcpy(dst, src, len));
   1048   ASSERT_TRUE(memcmp(src, dst, len) == 0);
   1049 }
   1050 
   1051 TEST(STRING_TEST, memcpy_align) {
   1052   RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
   1053 }
   1054 
   1055 TEST(STRING_TEST, memcpy_overread) {
   1056   RunSrcDstBufferOverreadTest(DoMemcpyTest);
   1057 }
   1058 
   1059 static void DoMemmoveTest(uint8_t* src, uint8_t* dst, size_t len) {
   1060   memset(src, (len % 255) + 1, len);
   1061   memset(dst, 0, len);
   1062 
   1063   ASSERT_EQ(dst, memmove(dst, src, len));
   1064   ASSERT_TRUE(memcmp(src, dst, len) == 0);
   1065 }
   1066 
   1067 TEST(STRING_TEST, memmove_align) {
   1068   RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
   1069 }
   1070 
   1071 TEST(STRING_TEST, memmove_overread) {
   1072   RunSrcDstBufferOverreadTest(DoMemmoveTest);
   1073 }
   1074 
   1075 static void DoMemsetTest(uint8_t* buf, size_t len) {
   1076   for (size_t i = 0; i < len; i++) {
   1077     buf[i] = 0;
   1078   }
   1079   int value = (len % 255) + 1;
   1080   ASSERT_EQ(buf, memset(buf, value, len));
   1081   for (size_t i = 0; i < len; i++) {
   1082     ASSERT_EQ(value, buf[i]);
   1083   }
   1084 }
   1085 
   1086 TEST(STRING_TEST, memset_align) {
   1087   RunSingleBufferAlignTest(LARGE, DoMemsetTest);
   1088 }
   1089 
   1090 static void DoStrlenTest(uint8_t* buf, size_t len) {
   1091   if (len >= 1) {
   1092     memset(buf, (32 + (len % 96)), len - 1);
   1093     buf[len-1] = '\0';
   1094     ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf)));
   1095   }
   1096 }
   1097 
   1098 TEST(STRING_TEST, strlen_align) {
   1099   RunSingleBufferAlignTest(LARGE, DoStrlenTest);
   1100 }
   1101 
   1102 TEST(STRING_TEST, strlen_overread) {
   1103   RunSingleBufferOverreadTest(DoStrlenTest);
   1104 }
   1105 
   1106 static void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
   1107   if (len >= 1) {
   1108     memset(src, (32 + (len % 96)), len - 1);
   1109     src[len-1] = '\0';
   1110     memset(dst, 0, len);
   1111     ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst),
   1112                                                      reinterpret_cast<char*>(src))));
   1113     ASSERT_TRUE(memcmp(src, dst, len) == 0);
   1114   }
   1115 }
   1116 
   1117 TEST(STRING_TEST, strcpy_align) {
   1118   RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
   1119 }
   1120 
   1121 TEST(STRING_TEST, strcpy_overread) {
   1122   RunSrcDstBufferOverreadTest(DoStrcpyTest);
   1123 }
   1124 
   1125 #if defined(STRLCPY_SUPPORTED)
   1126 static void DoStrlcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
   1127   if (len >= 1) {
   1128     memset(src, (32 + (len % 96)), len - 1);
   1129     src[len-1] = '\0';
   1130     memset(dst, 0, len);
   1131     ASSERT_EQ(len-1, strlcpy(reinterpret_cast<char*>(dst),
   1132                              reinterpret_cast<char*>(src), len));
   1133     ASSERT_TRUE(memcmp(src, dst, len) == 0);
   1134   }
   1135 }
   1136 #endif
   1137 
   1138 TEST(STRING_TEST, strlcpy_align) {
   1139 #if defined(STRLCPY_SUPPORTED)
   1140   RunSrcDstBufferAlignTest(LARGE, DoStrlcpyTest);
   1141 #else
   1142   GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
   1143 #endif
   1144 }
   1145 
   1146 TEST(STRING_TEST, strlcpy_overread) {
   1147 #if defined(STRLCPY_SUPPORTED)
   1148   RunSrcDstBufferOverreadTest(DoStrlcpyTest);
   1149 #else
   1150   GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
   1151 #endif
   1152 }
   1153 
   1154 
   1155 static void DoStpcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
   1156   if (len >= 1) {
   1157     memset(src, (32 + (len % 96)), len - 1);
   1158     src[len-1] = '\0';
   1159     memset(dst, 0, len);
   1160     ASSERT_EQ(dst+len-1, reinterpret_cast<uint8_t*>(stpcpy(reinterpret_cast<char*>(dst),
   1161                                                            reinterpret_cast<char*>(src))));
   1162     ASSERT_TRUE(memcmp(src, dst, len) == 0);
   1163   }
   1164 }
   1165 
   1166 TEST(STRING_TEST, stpcpy_align) {
   1167   RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest);
   1168 }
   1169 
   1170 TEST(STRING_TEST, stpcpy_overread) {
   1171   RunSrcDstBufferOverreadTest(DoStpcpyTest);
   1172 }
   1173 
   1174 // Use our own incrementer to cut down on the total number of calls.
   1175 static size_t LargeSetIncrement(size_t len) {
   1176   if (len >= 4096) {
   1177     return 4096;
   1178   } else if (len >= 1024) {
   1179     return 1024;
   1180   } else if (len >= 256) {
   1181     return 256;
   1182   }
   1183   return 1;
   1184 }
   1185 
   1186 #define STRCAT_DST_LEN  64
   1187 
   1188 static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) {
   1189   if (len >= 1) {
   1190     int value = 32 + (len % 96);
   1191     memset(src, value, len - 1);
   1192     src[len-1] = '\0';
   1193 
   1194     if (len >= STRCAT_DST_LEN) {
   1195       // Create a small buffer for doing quick compares in each loop.
   1196       uint8_t cmp_buf[STRCAT_DST_LEN];
   1197       // Make sure dst string contains a different value then the src string.
   1198       int value2 = 32 + (value + 2) % 96;
   1199       memset(cmp_buf, value2, sizeof(cmp_buf));
   1200 
   1201       for (size_t i = 1; i <= STRCAT_DST_LEN;) {
   1202         memset(dst, value2, i-1);
   1203         memset(dst+i-1, 0, len-i);
   1204         src[len-i] = '\0';
   1205         ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
   1206                                                          reinterpret_cast<char*>(src))));
   1207         ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
   1208         ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
   1209         // This is an expensive loop, so don't loop through every value,
   1210         // get to a certain size and then start doubling.
   1211         if (i < 16) {
   1212           i++;
   1213         } else {
   1214           i <<= 1;
   1215         }
   1216       }
   1217     } else {
   1218       dst[0] = '\0';
   1219       ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
   1220                                                        reinterpret_cast<char*>(src))));
   1221       ASSERT_TRUE(memcmp(src, dst, len) == 0);
   1222     }
   1223   }
   1224 }
   1225 
   1226 TEST(STRING_TEST, strcat_align) {
   1227   RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement);
   1228 }
   1229 
   1230 TEST(STRING_TEST, strcat_overread) {
   1231   RunSrcDstBufferOverreadTest(DoStrcatTest);
   1232 }
   1233 
   1234 #if defined(STRLCAT_SUPPORTED)
   1235 static void DoStrlcatTest(uint8_t* src, uint8_t* dst, size_t len) {
   1236   if (len >= 1) {
   1237     int value = 32 + (len % 96);
   1238     memset(src, value, len - 1);
   1239     src[len-1] = '\0';
   1240 
   1241     if (len >= STRCAT_DST_LEN) {
   1242       // Create a small buffer for doing quick compares in each loop.
   1243       uint8_t cmp_buf[STRCAT_DST_LEN];
   1244       // Make sure dst string contains a different value then the src string.
   1245       int value2 = 32 + (value + 2) % 96;
   1246       memset(cmp_buf, value2, sizeof(cmp_buf));
   1247 
   1248       for (size_t i = 1; i <= STRCAT_DST_LEN;) {
   1249         memset(dst, value2, i-1);
   1250         memset(dst+i-1, 0, len-i);
   1251         src[len-i] = '\0';
   1252         ASSERT_EQ(len-1, strlcat(reinterpret_cast<char*>(dst),
   1253                                  reinterpret_cast<char*>(src), len));
   1254         ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
   1255         ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
   1256         // This is an expensive loop, so don't loop through every value,
   1257         // get to a certain size and then start doubling.
   1258         if (i < 16) {
   1259           i++;
   1260         } else {
   1261           i <<= 1;
   1262         }
   1263       }
   1264     } else {
   1265       dst[0] = '\0';
   1266       ASSERT_EQ(len-1, strlcat(reinterpret_cast<char*>(dst),
   1267                                reinterpret_cast<char*>(src), len));
   1268       ASSERT_TRUE(memcmp(src, dst, len) == 0);
   1269     }
   1270   }
   1271 }
   1272 #endif
   1273 
   1274 TEST(STRING_TEST, strlcat_align) {
   1275 #if defined(STRLCAT_SUPPORTED)
   1276   RunSrcDstBufferAlignTest(MEDIUM, DoStrlcatTest, LargeSetIncrement);
   1277 #else
   1278   GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
   1279 #endif
   1280 }
   1281 
   1282 TEST(STRING_TEST, strlcat_overread) {
   1283 #if defined(STRLCAT_SUPPORTED)
   1284   RunSrcDstBufferOverreadTest(DoStrlcatTest);
   1285 #else
   1286   GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
   1287 #endif
   1288 }
   1289 
   1290 static void DoStrcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
   1291   if (len >= 1) {
   1292     memset(buf1, (32 + (len % 96)), len - 1);
   1293     buf1[len-1] = '\0';
   1294     memset(buf2, (32 + (len % 96)), len - 1);
   1295     buf2[len-1] = '\0';
   1296     ASSERT_EQ(0, strcmp(reinterpret_cast<char*>(buf1),
   1297                         reinterpret_cast<char*>(buf2)));
   1298   }
   1299 }
   1300 
   1301 static void DoStrcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
   1302   // Do string length differences.
   1303   int c = (32 + (len1 % 96));
   1304   memset(buf1, c, len1 - 1);
   1305   buf1[len1-1] = '\0';
   1306   memset(buf2, c, len2 - 1);
   1307   buf2[len2-1] = '\0';
   1308   ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
   1309                       reinterpret_cast<char*>(buf2)));
   1310 
   1311   // Do single character differences.
   1312   size_t len;
   1313   if (len1 > len2) {
   1314     len = len2;
   1315   } else {
   1316     len = len1;
   1317   }
   1318   // Need at least a two character buffer to do this test.
   1319   if (len > 1) {
   1320     buf1[len-1] = '\0';
   1321     buf2[len-1] = '\0';
   1322     int diff_c = (c + 1) % 96;
   1323 
   1324     buf1[len-2] = diff_c;
   1325     ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
   1326                         reinterpret_cast<char*>(buf2)));
   1327 
   1328     buf1[len-2] = c;
   1329     buf2[len-2] = diff_c;
   1330     ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
   1331                         reinterpret_cast<char*>(buf2)));
   1332   }
   1333 }
   1334 
   1335 TEST(STRING_TEST, strcmp_align) {
   1336   RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement);
   1337 }
   1338 
   1339 TEST(STRING_TEST, strcmp_overread) {
   1340   RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest);
   1341 }
   1342 
   1343 static void DoMemcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
   1344   memset(buf1, len+1, len);
   1345   memset(buf2, len+1, len);
   1346   ASSERT_EQ(0, memcmp(buf1, buf2, len));
   1347 }
   1348 
   1349 static void DoMemcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
   1350   size_t len;
   1351   if (len1 > len2) {
   1352     len = len2;
   1353   } else {
   1354     len = len1;
   1355   }
   1356 
   1357   memset(buf1, len2+1, len);
   1358   buf1[len-1] = len2;
   1359   memset(buf2, len2+1, len);
   1360   ASSERT_NE(0, memcmp(buf1, buf2, len));
   1361 
   1362   buf1[len-1] = len2+1;
   1363   buf2[len-1] = len2;
   1364   ASSERT_NE(0, memcmp(buf1, buf2, len));
   1365 }
   1366 
   1367 TEST(STRING_TEST, memcmp_align) {
   1368   RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement);
   1369 }
   1370 
   1371 TEST(STRING_TEST, memcmp_overread) {
   1372   RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
   1373 }
   1374 
   1375 static void DoMemchrTest(uint8_t* buf, size_t len) {
   1376   if (len >= 1) {
   1377     int value = len % 128;
   1378     int search_value = (len % 128) + 1;
   1379     memset(buf, value, len);
   1380     // The buffer does not contain the search value.
   1381     ASSERT_EQ(nullptr, memchr(buf, search_value, len));
   1382     if (len >= 2) {
   1383       buf[0] = search_value;
   1384       // The search value is the first element in the buffer.
   1385       ASSERT_EQ(&buf[0], memchr(buf, search_value, len));
   1386 
   1387       buf[0] = value;
   1388       buf[len - 1] = search_value;
   1389       // The search value is the last element in the buffer.
   1390       ASSERT_EQ(&buf[len - 1], memchr(buf, search_value, len));
   1391     }
   1392   }
   1393 }
   1394 
   1395 TEST(STRING_TEST, memchr_align) {
   1396   RunSingleBufferAlignTest(MEDIUM, DoMemchrTest);
   1397 }
   1398 
   1399 TEST(STRING_TEST, memchr_overread) {
   1400   RunSingleBufferOverreadTest(DoMemchrTest);
   1401 }
   1402 
   1403 static void DoStrchrTest(uint8_t* buf, size_t len) {
   1404   if (len >= 1) {
   1405     char value = 32 + (len % 96);
   1406     char search_value = 33 + (len % 96);
   1407     memset(buf, value, len - 1);
   1408     buf[len - 1] = '\0';
   1409     // The buffer does not contain the search value.
   1410     ASSERT_EQ(nullptr, strchr(reinterpret_cast<char*>(buf), search_value));
   1411     // Search for the special '\0' character.
   1412     ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 1]), strchr(reinterpret_cast<char*>(buf), '\0'));
   1413     if (len >= 2) {
   1414       buf[0] = search_value;
   1415       // The search value is the first element in the buffer.
   1416       ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strchr(reinterpret_cast<char*>(buf),
   1417                                                          search_value));
   1418 
   1419       buf[0] = value;
   1420       buf[len - 2] = search_value;
   1421       // The search value is the second to last element in the buffer.
   1422       // The last element is the '\0' character.
   1423       ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 2]), strchr(reinterpret_cast<char*>(buf),
   1424                                                                search_value));
   1425     }
   1426   }
   1427 }
   1428 
   1429 TEST(STRING_TEST, strchr_align) {
   1430   RunSingleBufferAlignTest(MEDIUM, DoStrchrTest);
   1431 }
   1432 
   1433 TEST(STRING_TEST, strchr_overread) {
   1434   RunSingleBufferOverreadTest(DoStrchrTest);
   1435 }
   1436 
   1437 static void DoStrrchrTest(uint8_t* buf, size_t len) {
   1438   if (len >= 1) {
   1439     char value = 32 + (len % 96);
   1440     char search_value = 33 + (len % 96);
   1441     memset(buf, value, len - 1);
   1442     buf[len - 1] = '\0';
   1443     // The buffer does not contain the search value.
   1444     ASSERT_EQ(nullptr, strrchr(reinterpret_cast<char*>(buf), search_value));
   1445     // Search for the special '\0' character.
   1446     ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 1]), strrchr(reinterpret_cast<char*>(buf), '\0'));
   1447     if (len >= 2) {
   1448       buf[0] = search_value;
   1449       // The search value is the first element in the buffer.
   1450       ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strrchr(reinterpret_cast<char*>(buf),
   1451                                                           search_value));
   1452 
   1453       buf[0] = value;
   1454       buf[len - 2] = search_value;
   1455       // The search value is the second to last element in the buffer.
   1456       // The last element is the '\0' character.
   1457       ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 2]), strrchr(reinterpret_cast<char*>(buf),
   1458                                                                 search_value));
   1459     }
   1460   }
   1461 }
   1462 
   1463 TEST(STRING_TEST, strrchr_align) {
   1464   RunSingleBufferAlignTest(MEDIUM, DoStrrchrTest);
   1465 }
   1466 
   1467 TEST(STRING_TEST, strrchr_overread) {
   1468   RunSingleBufferOverreadTest(DoStrrchrTest);
   1469 }
   1470 
   1471 static void TestBasename(const char* in, const char* expected_out) {
   1472   errno = 0;
   1473   const char* out = basename(in);
   1474   ASSERT_STREQ(expected_out, out) << in;
   1475   ASSERT_EQ(0, errno) << in;
   1476 }
   1477 
   1478 TEST(STRING_TEST, __gnu_basename) {
   1479   TestBasename("", "");
   1480   TestBasename("/usr/lib", "lib");
   1481   TestBasename("/usr/", "");
   1482   TestBasename("usr", "usr");
   1483   TestBasename("/", "");
   1484   TestBasename(".", ".");
   1485   TestBasename("..", "..");
   1486   TestBasename("///", "");
   1487   TestBasename("//usr//lib//", "");
   1488 }
   1489 
   1490 TEST(STRING_TEST, strnlen_147048) {
   1491   // https://code.google.com/p/android/issues/detail?id=147048
   1492   char stack_src[64] = {0};
   1493   EXPECT_EQ(0U, strnlen(stack_src, 1024*1024*1024));
   1494   char* heap_src = new char[1];
   1495   *heap_src = '\0';
   1496   EXPECT_EQ(0U, strnlen(heap_src, 1024*1024*1024));
   1497   delete[] heap_src;
   1498 }
   1499 
   1500 TEST(STRING_TEST, strnlen_74741) {
   1501   ASSERT_EQ(4U, strnlen("test", SIZE_MAX));
   1502 }
   1503 
   1504 TEST(STRING_TEST, mempcpy) {
   1505   char dst[6];
   1506   ASSERT_EQ(&dst[4], reinterpret_cast<char*>(mempcpy(dst, "hello", 4)));
   1507 }
   1508 
   1509 // clang depends on the fact that a memcpy where src and dst is the same
   1510 // still operates correctly. This test verifies that this assumption
   1511 // holds true.
   1512 // See https://llvm.org/bugs/show_bug.cgi?id=11763 for more information.
   1513 static std::vector<uint8_t> g_memcpy_same_buffer;
   1514 
   1515 static void DoMemcpySameTest(uint8_t* buffer, size_t len) {
   1516   memcpy(buffer, g_memcpy_same_buffer.data(), len);
   1517   ASSERT_EQ(buffer, memcpy(buffer, buffer, len));
   1518   ASSERT_TRUE(memcmp(buffer, g_memcpy_same_buffer.data(), len) == 0);
   1519 }
   1520 
   1521 TEST(STRING_TEST, memcpy_src_dst_same) {
   1522   g_memcpy_same_buffer.resize(MEDIUM);
   1523   for (size_t i = 0; i < MEDIUM; i++) {
   1524     g_memcpy_same_buffer[i] = i;
   1525   }
   1526   RunSingleBufferAlignTest(MEDIUM, DoMemcpySameTest);
   1527 }
   1528 
   1529 TEST(STRING_TEST, memmem_strstr_empty_needle) {
   1530   const char* some_haystack = "haystack";
   1531   const char* empty_haystack = "";
   1532 
   1533   ASSERT_EQ(some_haystack, memmem(some_haystack, 8, "", 0));
   1534   ASSERT_EQ(empty_haystack, memmem(empty_haystack, 0, "", 0));
   1535 
   1536   ASSERT_EQ(some_haystack, strstr(some_haystack, ""));
   1537   ASSERT_EQ(empty_haystack, strstr(empty_haystack, ""));
   1538 }
   1539 
   1540 TEST(STRING_TEST, memmem_smoke) {
   1541   const char haystack[] = "big\0daddy\0giant\0haystacks";
   1542   ASSERT_EQ(haystack, memmem(haystack, sizeof(haystack), "", 0));
   1543   ASSERT_EQ(haystack + 3, memmem(haystack, sizeof(haystack), "", 1));
   1544   ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "b", 1));
   1545   ASSERT_EQ(haystack + 1, memmem(haystack, sizeof(haystack), "i", 1));
   1546   ASSERT_EQ(haystack + 4, memmem(haystack, sizeof(haystack), "da", 2));
   1547   ASSERT_EQ(haystack + 8, memmem(haystack, sizeof(haystack), "y\0g", 3));
   1548 }
   1549 
   1550 TEST(STRING_TEST, strstr_smoke) {
   1551   const char* haystack = "big daddy/giant haystacks";
   1552   ASSERT_EQ(haystack, strstr(haystack, ""));
   1553   ASSERT_EQ(haystack + 0, strstr(haystack, "b"));
   1554   ASSERT_EQ(haystack + 1, strstr(haystack, "i"));
   1555   ASSERT_EQ(haystack + 4, strstr(haystack, "da"));
   1556 }
   1557