string_test.cpp revision 606058933c5129cb1026960ea67624b9426c610f
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
27static 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
36TEST(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
48static void* ConcurrentStrErrorFn(void*) {
49  bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
50  return reinterpret_cast<void*>(equal);
51}
52
53TEST(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.
69TEST(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
90TEST(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
107static void* ConcurrentStrSignalFn(void*) {
108  bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
109  return reinterpret_cast<void*>(equal);
110}
111
112TEST(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.
134struct StringTestState {
135  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
148  ~StringTestState() {
149    free(glob_ptr);
150    free(glob_ptr1);
151    free(glob_ptr2);
152  }
153
154  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.
177  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
190TEST(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
212TEST(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
245TEST(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
282TEST(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.
312TEST(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#endif
320
321#if __BIONIC__
322TEST(string, strlcat) {
323  StringTestState state(SMALL);
324  for (size_t i = 0; i < state.n; i++) {
325    for (size_t j = 0; j < POS_ITER; j++) {
326      state.NewIteration();
327
328      memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
329      state.ptr2[state.MAX_LEN - 1] = '\0';
330      memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
331
332      int pos = random() % state.MAX_LEN;
333      memset(state.ptr1, '\3', pos);
334      state.ptr1[pos] = '\0';
335      if (pos < state.len[i]) {
336        memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
337      } else {
338        memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
339        state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
340      }
341
342      strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
343
344      ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
345    }
346  }
347}
348#endif
349
350#if __BIONIC__
351TEST(string, strlcpy) {
352  StringTestState state(SMALL);
353  for (size_t j = 0; j < POS_ITER; j++) {
354    state.NewIteration();
355
356    int rand = random() & 255;
357    if (rand < 1) {
358      rand = 1;
359    }
360    memset(state.ptr1, rand, state.MAX_LEN);
361
362    size_t pos = random() % state.MAX_LEN;
363    if (pos < state.MAX_LEN) {
364      state.ptr1[pos] = '\0';
365    }
366    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
367
368    memset(state.ptr2, random() & 255, state.MAX_LEN);
369    memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
370
371    if (pos > state.MAX_LEN - 1) {
372      memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
373      state.ptr[2 * state.MAX_LEN - 1] = '\0';
374    } else {
375      memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
376    }
377
378    ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
379    ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
380                 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
381  }
382}
383#endif
384
385TEST(string, strncat) {
386  StringTestState state(SMALL);
387  for (size_t i = 1; i < state.n; i++) {
388    for (size_t j = 0; j < POS_ITER; j++) {
389      state.NewIteration();
390
391      memset(state.ptr2, '\2', state.MAX_LEN);
392      state.ptr2[state.MAX_LEN - 1] = '\0';
393      memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
394
395      memset(state.ptr1, random() & 255, state.len[i]);
396      state.ptr1[random() % state.len[i]] = '\0';
397      state.ptr1[state.len[i] - 1] = '\0';
398
399      size_t pos = strlen(state.ptr1);
400
401      size_t actual = random() % state.len[i];
402      strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
403      state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
404
405      ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
406      ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
407    }
408  }
409}
410
411TEST(string, strncmp) {
412  StringTestState state(SMALL);
413  for (size_t i = 1; i < state.n; i++) {
414    for (size_t j = 0; j < POS_ITER; j++) {
415      state.NewIteration();
416
417      memset(state.ptr1, 'v', state.MAX_LEN);
418      memset(state.ptr2, 'n', state.MAX_LEN);
419      state.ptr1[state.len[i] - 1] = '\0';
420      state.ptr2[state.len[i] - 1] = '\0';
421
422      int pos = 1 + (random() % (state.MAX_LEN - 1));
423      int actual;
424      int expected;
425      if (pos >= state.len[i] - 1) {
426        memcpy(state.ptr1, state.ptr2, state.len[i]);
427        expected = 0;
428        actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
429      } else {
430        memcpy(state.ptr1, state.ptr2, pos);
431        if (state.ptr1[pos] > state.ptr2[pos]) {
432          expected = 1;
433        } else if (state.ptr1[pos] == state.ptr2[pos]) {
434          state.ptr1[pos + 1] = '\0';
435          state.ptr2[pos + 1] = '\0';
436          expected = 0;
437        } else {
438          expected = -1;
439        }
440        actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
441      }
442
443      ASSERT_EQ(expected, signum(actual));
444    }
445  }
446}
447
448TEST(string, strncpy) {
449  StringTestState state(SMALL);
450  for (size_t j = 0; j < ITER; j++) {
451    state.NewIteration();
452
453    memset(state.ptr1, random() & 255, state.MAX_LEN);
454    state.ptr1[random () % state.MAX_LEN] = '\0';
455    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
456
457    memset(state.ptr2, '\1', state.MAX_LEN);
458
459    size_t pos;
460    if (memchr(state.ptr1, 0, state.MAX_LEN)) {
461      pos = strlen(state.ptr1);
462    } else {
463      pos = state.MAX_LEN - 1;
464    }
465
466    memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN);
467    memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
468
469    ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2);
470    ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 ||
471                 memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0);
472  }
473}
474
475TEST(string, strrchr) {
476  int seek_char = random() & 255;
477  StringTestState state(SMALL);
478  for (size_t i = 1; i < state.n; i++) {
479    for (size_t j = 0; j < POS_ITER; j++) {
480      state.NewIteration();
481
482      if (~seek_char > 0) {
483        memset(state.ptr1, ~seek_char, state.len[i]);
484      } else {
485        memset(state.ptr1, '\1', state.len[i]);
486      }
487      state.ptr1[state.len[i] - 1] = '\0';
488
489      int pos = random() % state.MAX_LEN;
490      char* expected;
491      if (pos >= state.len[i] - 1) {
492        if (seek_char == 0) {
493          expected = state.ptr1 + state.len[i] - 1;
494        } else {
495          expected = NULL;
496        }
497      } else {
498        state.ptr1[pos] = seek_char;
499        expected = state.ptr1 + pos;
500      }
501
502      ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
503    }
504  }
505}
506
507TEST(string, memchr) {
508  int seek_char = random() & 255;
509  StringTestState state(SMALL);
510  for (size_t i = 0; i < state.n; i++) {
511    for (size_t j = 0; j < POS_ITER; j++) {
512      state.NewIteration();
513
514      memset(state.ptr1, ~seek_char, state.len[i]);
515
516      int pos = random() % state.MAX_LEN;
517      char* expected;
518      if (pos >= state.len[i]) {
519        expected = NULL;
520      } else {
521        state.ptr1[pos] = seek_char;
522        expected = state.ptr1 + pos;
523      }
524
525      ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
526    }
527  }
528}
529
530TEST(string, memrchr) {
531  int seek_char = random() & 255;
532  StringTestState state(SMALL);
533  for (size_t i = 0; i < state.n; i++) {
534    for (size_t j = 0; j < POS_ITER; j++) {
535      state.NewIteration();
536
537      memset(state.ptr1, ~seek_char, state.len[i]);
538
539      int pos = random() % state.MAX_LEN;
540      char* expected;
541      if (pos >= state.len[i]) {
542        expected = NULL;
543      } else {
544        state.ptr1[pos] = seek_char;
545        expected = state.ptr1 + pos;
546      }
547
548      ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
549    }
550  }
551}
552
553TEST(string, memcmp) {
554  StringTestState state(SMALL);
555  for (size_t i = 0; i < state.n; i++) {
556    for (size_t j = 0; j < POS_ITER; j++) {
557      state.NewIteration();
558
559      int c1 = random() & 0xff;
560      int c2 = random() & 0xff;
561      memset(state.ptr1, c1, state.MAX_LEN);
562      memset(state.ptr2, c1, state.MAX_LEN);
563
564      int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
565      state.ptr2[pos] = c2;
566
567      int expected = (static_cast<int>(c1) - static_cast<int>(c2));
568      int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
569
570      ASSERT_EQ(signum(expected), signum(actual));
571    }
572  }
573}
574
575TEST(string, memcpy) {
576  StringTestState state(LARGE);
577  int rand = random() & 255;
578  for (size_t i = 0; i < state.n - 1; i++) {
579    for (size_t j = 0; j < POS_ITER; j++) {
580      state.NewIteration();
581
582      size_t pos = random() % (state.MAX_LEN - state.len[i]);
583
584      memset(state.ptr1, rand, state.len[i]);
585      memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
586
587      memset(state.ptr2, rand, state.len[i]);
588      memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
589      memset(state.ptr2 + pos, '\0', state.len[i]);
590
591      ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
592      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
593    }
594  }
595}
596
597TEST(string, memset) {
598  StringTestState state(LARGE);
599  char ch = random () & 255;
600  for (size_t i = 0; i < state.n - 1; i++) {
601    for (size_t j = 0; j < POS_ITER; j++) {
602      state.NewIteration();
603
604      memset(state.ptr1, ~ch, state.MAX_LEN);
605      memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
606
607      size_t pos = random () % (state.MAX_LEN - state.len[i]);
608      for (size_t k = pos; k < pos + state.len[i]; k++) {
609        state.ptr1[k] = ch;
610      }
611
612      ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
613
614      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
615    }
616  }
617}
618
619TEST(string, memmove) {
620  StringTestState state(LARGE);
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, random() & 255, 2 * state.MAX_LEN);
626
627      size_t pos = random() % (state.MAX_LEN - state.len[i]);
628
629      memset(state.ptr1, random() & 255, state.len[i]);
630      memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
631      memcpy(state.ptr, state.ptr1, state.len[i]);
632      memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
633
634      ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
635      ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
636    }
637  }
638}
639
640TEST(string, bcopy) {
641  StringTestState state(LARGE);
642  for (size_t i = 0; i < state.n; i++) {
643    for (size_t j = 0; j < POS_ITER; j++) {
644      state.NewIteration();
645
646      memset(state.ptr1, random() & 255, state.MAX_LEN);
647      memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN);
648      memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
649
650      size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
651      memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
652
653      bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
654      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
655    }
656  }
657}
658
659TEST(string, bzero) {
660  StringTestState state(LARGE);
661  for (size_t j = 0; j < ITER; j++) {
662    state.NewIteration();
663
664    memset(state.ptr1, random() & 255, state.MAX_LEN);
665
666    size_t start = random() % state.MAX_LEN;
667    size_t end = start + random() % (state.MAX_LEN - start);
668
669    memcpy(state.ptr2, state.ptr1, start);
670    memset(state.ptr2 + start, '\0', end - start);
671    memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
672
673    bzero(state.ptr1 + start, end - start);
674
675    ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
676  }
677}
678