string_test.cpp revision 4f40e511b0612ea099ab5b0843977fe7a49372fd
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_with_0) {
213  char buf[10];
214  const char* s = "01234";
215  memcpy(buf, s, strlen(s) + 1);
216  EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
217}
218
219TEST(string, strchr) {
220  int seek_char = random() & 255;
221
222  StringTestState state(SMALL);
223  for (size_t i = 1; i < state.n; i++) {
224    for (size_t j = 0; j < POS_ITER; j++) {
225      state.NewIteration();
226
227      if (~seek_char > 0) {
228        memset(state.ptr1, ~seek_char, state.len[i]);
229      } else {
230        memset(state.ptr1, '\1', state.len[i]);
231      }
232      state.ptr1[state.len[i] - 1] = '\0';
233
234      int pos = random() % state.MAX_LEN;
235      char* expected;
236      if (pos >= state.len[i] - 1) {
237        if (seek_char == 0) {
238          expected = state.ptr1 + state.len[i] - 1;
239        } else {
240          expected = NULL;
241        }
242      } else {
243        state.ptr1[pos] = seek_char;
244        expected = state.ptr1 + pos;
245      }
246
247      ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
248    }
249  }
250}
251
252TEST(string, strcmp) {
253  StringTestState state(SMALL);
254  for (size_t i = 1; i < state.n; i++) {
255    for (size_t j = 0; j < POS_ITER; j++) {
256      state.NewIteration();
257
258      memset(state.ptr1, 'v', state.MAX_LEN);
259      memset(state.ptr2, 'n', state.MAX_LEN);
260      state.ptr1[state.len[i] - 1] = '\0';
261      state.ptr2[state.len[i] - 1] = '\0';
262
263      int pos = 1 + (random() % (state.MAX_LEN - 1));
264      int actual;
265      int expected;
266      if (pos >= state.len[i] - 1) {
267        memcpy(state.ptr1, state.ptr2, state.len[i]);
268        expected = 0;
269        actual = strcmp(state.ptr1, state.ptr2);
270      } else {
271        memcpy(state.ptr1, state.ptr2, pos);
272        if (state.ptr1[pos] > state.ptr2[pos]) {
273          expected = 1;
274        } else if (state.ptr1[pos] == state.ptr2[pos]) {
275          state.ptr1[pos + 1] = '\0';
276          state.ptr2[pos + 1] = '\0';
277          expected = 0;
278        } else {
279          expected = -1;
280        }
281        actual = strcmp(state.ptr1, state.ptr2);
282      }
283
284      ASSERT_EQ(expected, signum(actual));
285    }
286  }
287}
288
289TEST(string, strcpy) {
290  StringTestState state(SMALL);
291  for (size_t j = 0; j < POS_ITER; j++) {
292    state.NewIteration();
293
294    size_t pos = random() % state.MAX_LEN;
295
296    memset(state.ptr1, '\2', pos);
297    state.ptr1[pos] = '\0';
298    state.ptr1[state.MAX_LEN - 1] = '\0';
299
300    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
301
302    memset(state.ptr2, '\1', state.MAX_LEN);
303    state.ptr2[state.MAX_LEN - 1] = '\0';
304
305    memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
306    memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
307    state.ptr[2 * state.MAX_LEN - 1] = '\0';
308
309    ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
310    ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
311                 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
312  }
313}
314
315
316#if __BIONIC__
317TEST(string, strlcat) {
318  StringTestState state(SMALL);
319  for (size_t i = 0; i < state.n; i++) {
320    for (size_t j = 0; j < POS_ITER; j++) {
321      state.NewIteration();
322
323      memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
324      state.ptr2[state.MAX_LEN - 1] = '\0';
325      memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
326
327      int pos = random() % state.MAX_LEN;
328      memset(state.ptr1, '\3', pos);
329      state.ptr1[pos] = '\0';
330      if (pos < state.len[i]) {
331        memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
332      } else {
333        memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
334        state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
335      }
336
337      strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
338
339      ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
340    }
341  }
342}
343#endif
344
345#if __BIONIC__
346TEST(string, strlcpy) {
347  StringTestState state(SMALL);
348  for (size_t j = 0; j < POS_ITER; j++) {
349    state.NewIteration();
350
351    int rand = random() & 255;
352    if (rand < 1) {
353      rand = 1;
354    }
355    memset(state.ptr1, rand, state.MAX_LEN);
356
357    size_t pos = random() % state.MAX_LEN;
358    if (pos < state.MAX_LEN) {
359      state.ptr1[pos] = '\0';
360    }
361    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
362
363    memset(state.ptr2, random() & 255, state.MAX_LEN);
364    memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
365
366    if (pos > state.MAX_LEN - 1) {
367      memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
368      state.ptr[2 * state.MAX_LEN - 1] = '\0';
369    } else {
370      memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
371    }
372
373    ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
374    ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
375                 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
376  }
377}
378#endif
379
380TEST(string, strncat) {
381  StringTestState state(SMALL);
382  for (size_t i = 1; i < state.n; i++) {
383    for (size_t j = 0; j < POS_ITER; j++) {
384      state.NewIteration();
385
386      memset(state.ptr2, '\2', state.MAX_LEN);
387      state.ptr2[state.MAX_LEN - 1] = '\0';
388      memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
389
390      memset(state.ptr1, random() & 255, state.len[i]);
391      state.ptr1[random() % state.len[i]] = '\0';
392      state.ptr1[state.len[i] - 1] = '\0';
393
394      size_t pos = strlen(state.ptr1);
395
396      size_t actual = random() % state.len[i];
397      strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
398      state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
399
400      ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
401      ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
402    }
403  }
404}
405
406TEST(string, strncmp) {
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.ptr1, 'v', state.MAX_LEN);
413      memset(state.ptr2, 'n', state.MAX_LEN);
414      state.ptr1[state.len[i] - 1] = '\0';
415      state.ptr2[state.len[i] - 1] = '\0';
416
417      int pos = 1 + (random() % (state.MAX_LEN - 1));
418      int actual;
419      int expected;
420      if (pos >= state.len[i] - 1) {
421        memcpy(state.ptr1, state.ptr2, state.len[i]);
422        expected = 0;
423        actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
424      } else {
425        memcpy(state.ptr1, state.ptr2, pos);
426        if (state.ptr1[pos] > state.ptr2[pos]) {
427          expected = 1;
428        } else if (state.ptr1[pos] == state.ptr2[pos]) {
429          state.ptr1[pos + 1] = '\0';
430          state.ptr2[pos + 1] = '\0';
431          expected = 0;
432        } else {
433          expected = -1;
434        }
435        actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
436      }
437
438      ASSERT_EQ(expected, signum(actual));
439    }
440  }
441}
442
443TEST(string, strncpy) {
444  StringTestState state(SMALL);
445  for (size_t j = 0; j < ITER; j++) {
446    state.NewIteration();
447
448    memset(state.ptr1, random() & 255, state.MAX_LEN);
449    state.ptr1[random () % state.MAX_LEN] = '\0';
450    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
451
452    memset(state.ptr2, '\1', state.MAX_LEN);
453
454    size_t pos;
455    if (memchr(state.ptr1, 0, state.MAX_LEN)) {
456      pos = strlen(state.ptr1);
457    } else {
458      pos = state.MAX_LEN - 1;
459    }
460
461    memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN);
462    memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
463
464    ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2);
465    ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 ||
466                 memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0);
467  }
468}
469
470TEST(string, strrchr) {
471  int seek_char = random() & 255;
472  StringTestState state(SMALL);
473  for (size_t i = 1; i < state.n; i++) {
474    for (size_t j = 0; j < POS_ITER; j++) {
475      state.NewIteration();
476
477      if (~seek_char > 0) {
478        memset(state.ptr1, ~seek_char, state.len[i]);
479      } else {
480        memset(state.ptr1, '\1', state.len[i]);
481      }
482      state.ptr1[state.len[i] - 1] = '\0';
483
484      int pos = random() % state.MAX_LEN;
485      char* expected;
486      if (pos >= state.len[i] - 1) {
487        if (seek_char == 0) {
488          expected = state.ptr1 + state.len[i] - 1;
489        } else {
490          expected = NULL;
491        }
492      } else {
493        state.ptr1[pos] = seek_char;
494        expected = state.ptr1 + pos;
495      }
496
497      ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
498    }
499  }
500}
501
502TEST(string, memchr) {
503  int seek_char = random() & 255;
504  StringTestState 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.ptr1, ~seek_char, state.len[i]);
510
511      int pos = random() % state.MAX_LEN;
512      char* expected;
513      if (pos >= state.len[i]) {
514        expected = NULL;
515      } else {
516        state.ptr1[pos] = seek_char;
517        expected = state.ptr1 + pos;
518      }
519
520      ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
521    }
522  }
523}
524
525TEST(string, memrchr) {
526  int seek_char = random() & 255;
527  StringTestState state(SMALL);
528  for (size_t i = 0; i < state.n; i++) {
529    for (size_t j = 0; j < POS_ITER; j++) {
530      state.NewIteration();
531
532      memset(state.ptr1, ~seek_char, state.len[i]);
533
534      int pos = random() % state.MAX_LEN;
535      char* expected;
536      if (pos >= state.len[i]) {
537        expected = NULL;
538      } else {
539        state.ptr1[pos] = seek_char;
540        expected = state.ptr1 + pos;
541      }
542
543      ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
544    }
545  }
546}
547
548TEST(string, memcmp) {
549  StringTestState state(SMALL);
550  for (size_t i = 0; i < state.n; i++) {
551    for (size_t j = 0; j < POS_ITER; j++) {
552      state.NewIteration();
553
554      int c1 = random() & 0xff;
555      int c2 = random() & 0xff;
556      memset(state.ptr1, c1, state.MAX_LEN);
557      memset(state.ptr2, c1, state.MAX_LEN);
558
559      int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
560      state.ptr2[pos] = c2;
561
562      int expected = (static_cast<int>(c1) - static_cast<int>(c2));
563      int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
564
565      ASSERT_EQ(signum(expected), signum(actual));
566    }
567  }
568}
569
570TEST(string, memcpy) {
571  StringTestState state(LARGE);
572  int rand = random() & 255;
573  for (size_t i = 0; i < state.n - 1; i++) {
574    for (size_t j = 0; j < POS_ITER; j++) {
575      state.NewIteration();
576
577      size_t pos = random() % (state.MAX_LEN - state.len[i]);
578
579      memset(state.ptr1, rand, state.len[i]);
580      memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
581
582      memset(state.ptr2, rand, state.len[i]);
583      memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
584      memset(state.ptr2 + pos, '\0', state.len[i]);
585
586      ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
587      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
588    }
589  }
590}
591
592TEST(string, memset) {
593  StringTestState state(LARGE);
594  char ch = random () & 255;
595  for (size_t i = 0; i < state.n - 1; i++) {
596    for (size_t j = 0; j < POS_ITER; j++) {
597      state.NewIteration();
598
599      memset(state.ptr1, ~ch, state.MAX_LEN);
600      memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
601
602      size_t pos = random () % (state.MAX_LEN - state.len[i]);
603      for (size_t k = pos; k < pos + state.len[i]; k++) {
604        state.ptr1[k] = ch;
605      }
606
607      ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
608
609      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
610    }
611  }
612}
613
614TEST(string, memmove) {
615  StringTestState state(LARGE);
616  for (size_t i = 0; i < state.n - 1; i++) {
617    for (size_t j = 0; j < POS_ITER; j++) {
618      state.NewIteration();
619
620      memset(state.ptr1, random() & 255, 2 * state.MAX_LEN);
621
622      size_t pos = random() % (state.MAX_LEN - state.len[i]);
623
624      memset(state.ptr1, random() & 255, state.len[i]);
625      memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
626      memcpy(state.ptr, state.ptr1, state.len[i]);
627      memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
628
629      ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
630      ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
631    }
632  }
633}
634
635TEST(string, bcopy) {
636  StringTestState state(LARGE);
637  for (size_t i = 0; i < state.n; i++) {
638    for (size_t j = 0; j < POS_ITER; j++) {
639      state.NewIteration();
640
641      memset(state.ptr1, random() & 255, state.MAX_LEN);
642      memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN);
643      memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
644
645      size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
646      memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
647
648      bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
649      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
650    }
651  }
652}
653
654TEST(string, bzero) {
655  StringTestState state(LARGE);
656  for (size_t j = 0; j < ITER; j++) {
657    state.NewIteration();
658
659    memset(state.ptr1, random() & 255, state.MAX_LEN);
660
661    size_t start = random() % state.MAX_LEN;
662    size_t end = start + random() % (state.MAX_LEN - start);
663
664    memcpy(state.ptr2, state.ptr1, start);
665    memset(state.ptr2 + start, '\0', end - start);
666    memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
667
668    bzero(state.ptr1 + start, end - start);
669
670    ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
671  }
672}
673