• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
signum(int i)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 
TEST(string,strerror)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__)
ConcurrentStrErrorFn(void *)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.
TEST(string,strerror_concurrent)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 
TEST(string,strerror_r)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 
TEST(string,strsignal)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 
ConcurrentStrSignalFn(void *)114 static void* ConcurrentStrSignalFn(void*) {
115   bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
116   return reinterpret_cast<void*>(equal);
117 }
118 
TEST(string,strsignal_concurrent)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 {
StringTestStateStringTestState143   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 
~StringTestStateStringTestState156   ~StringTestState() {
157     free(glob_ptr);
158     free(glob_ptr1);
159     free(glob_ptr2);
160   }
161 
NewIterationStringTestState162   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   int 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.
InitLenArrayStringTestState185   void InitLenArray() {
186     n = 0;
187     len[n++] = 0;
188     for (size_t i = 1; i < ITER; ++i) {
189       int l = (int) exp(log((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 
TEST(string,strcat)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
TEST(string,strcpy2)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
TEST(string,strcpy3)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
TEST(string,strcpy4)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
TEST(string,stpcpy2)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
TEST(string,stpcpy3)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
TEST(string,stpcpy4)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 
TEST(string,strcat2)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 
TEST(string,strcat3)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 
TEST(string,strncat2)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 
TEST(string,strncat3)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 
TEST(string,strncat4)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 
TEST(string,strncat5)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 
TEST(string,strchr_with_0)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 
TEST(string,strchr_multiple)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 
TEST(string,strchr)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       int 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 
TEST(string,strcmp)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       int 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 
TEST(string,stpcpy)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 
TEST(string,strcpy)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 
TEST(string,strlcat)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       int 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 
TEST(string,strlcpy)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 
TEST(string,strncat)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 
TEST(string,strncmp)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       int 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 
TEST(string,stpncpy)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 
TEST(string,strncpy)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 
TEST(string,strrchr)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       int 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 
TEST(string,memchr)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       int 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 
TEST(string,memchr_zero)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 
TEST(string,memrchr)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       int 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 
TEST(string,memcmp)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 
TEST(string,wmemcmp)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 
TEST(string,memcpy)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 
TEST(string,memset)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 
TEST(string,memmove)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 
TEST(string,memmove_cache_size)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 
verify_memmove(char * src_copy,char * dst,char * src,size_t size)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 
TEST(string,memmove_check)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 
TEST(string,bcopy)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 
TEST(string,bzero)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 
DoMemcpyTest(uint8_t * src,uint8_t * dst,size_t len)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 
TEST(string,memcpy_align)1034 TEST(string, memcpy_align) {
1035   RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
1036 }
1037 
TEST(string,memcpy_overread)1038 TEST(string, memcpy_overread) {
1039   RunSrcDstBufferOverreadTest(DoMemcpyTest);
1040 }
1041 
DoMemmoveTest(uint8_t * src,uint8_t * dst,size_t len)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 
TEST(string,memmove_align)1050 TEST(string, memmove_align) {
1051   RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
1052 }
1053 
TEST(string,memmove_overread)1054 TEST(string, memmove_overread) {
1055   RunSrcDstBufferOverreadTest(DoMemmoveTest);
1056 }
1057 
DoMemsetTest(uint8_t * buf,size_t len)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 
TEST(string,memset_align)1069 TEST(string, memset_align) {
1070   RunSingleBufferAlignTest(LARGE, DoMemsetTest);
1071 }
1072 
DoStrlenTest(uint8_t * buf,size_t len)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 
TEST(string,strlen_align)1081 TEST(string, strlen_align) {
1082   RunSingleBufferAlignTest(LARGE, DoStrlenTest);
1083 }
1084 
TEST(string,strlen_overread)1085 TEST(string, strlen_overread) {
1086   RunSingleBufferOverreadTest(DoStrlenTest);
1087 }
1088 
DoStrcpyTest(uint8_t * src,uint8_t * dst,size_t len)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 
TEST(string,strcpy_align)1100 TEST(string, strcpy_align) {
1101   RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
1102 }
1103 
TEST(string,strcpy_overread)1104 TEST(string, strcpy_overread) {
1105   RunSrcDstBufferOverreadTest(DoStrcpyTest);
1106 }
1107 
DoStpcpyTest(uint8_t * src,uint8_t * dst,size_t len)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 
TEST(string,stpcpy_align)1119 TEST(string, stpcpy_align) {
1120   RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest);
1121 }
1122 
TEST(string,stpcpy_overread)1123 TEST(string, stpcpy_overread) {
1124   RunSrcDstBufferOverreadTest(DoStpcpyTest);
1125 }
1126 
1127 // Use our own incrementer to cut down on the total number of calls.
LargeSetIncrement(size_t len)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 
DoStrcatTest(uint8_t * src,uint8_t * dst,size_t len)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 
TEST(string,strcat_align)1172 TEST(string, strcat_align) {
1173   RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement);
1174 }
1175 
TEST(string,strcat_overread)1176 TEST(string, strcat_overread) {
1177   RunSrcDstBufferOverreadTest(DoStrcatTest);
1178 }
1179 
DoStrcmpTest(uint8_t * buf1,uint8_t * buf2,size_t len)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 
DoStrcmpFailTest(uint8_t * buf1,uint8_t * buf2,size_t len1,size_t len2)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 
TEST(string,strcmp_align)1225 TEST(string, strcmp_align) {
1226   RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement);
1227 }
1228 
TEST(string,strcmp_overread)1229 TEST(string, strcmp_overread) {
1230   RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest);
1231 }
1232 
DoMemcmpTest(uint8_t * buf1,uint8_t * buf2,size_t len)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 
DoMemcmpFailTest(uint8_t * buf1,uint8_t * buf2,size_t len1,size_t len2)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 
TEST(string,memcmp_align)1257 TEST(string, memcmp_align) {
1258   RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement);
1259 }
1260 
TEST(string,memcmp_overread)1261 TEST(string, memcmp_overread) {
1262   RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
1263 }
1264 
DoStrchrTest(uint8_t * buf,size_t len)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 
TEST(string,strchr_align)1283 TEST(string, strchr_align) {
1284   RunSingleBufferAlignTest(MEDIUM, DoStrchrTest);
1285 }
1286 
TEST(string,strchr_overread)1287 TEST(string, strchr_overread) {
1288   RunSingleBufferOverreadTest(DoStrchrTest);
1289 }
1290