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