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