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