string_test.cpp revision baa91f4f8974b6e9a81fa3aa49f051b3bf823653
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.
134template<class Character>
135struct StringTestState {
136  StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) {
137    int max_alignment = 64;
138
139    // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
140    glob_ptr = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
141    glob_ptr1 = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
142    glob_ptr2 = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
143
144    InitLenArray();
145
146    srandom(1234);
147  }
148
149  ~StringTestState() {
150    free(glob_ptr);
151    free(glob_ptr1);
152    free(glob_ptr2);
153  }
154
155  void NewIteration() {
156    int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 };
157    int usable_alignments = 10;
158    int align1 = alignments[random() % (usable_alignments - 1)];
159    int align2 = alignments[random() % (usable_alignments - 1)];
160
161    ptr = glob_ptr + align1;
162    ptr1 = glob_ptr1 + align1;
163    ptr2 = glob_ptr2 + align2;
164  }
165
166  const size_t MAX_LEN;
167  Character *ptr, *ptr1, *ptr2;
168  size_t n;
169  int len[ITER + 1];
170
171 private:
172  Character *glob_ptr, *glob_ptr1, *glob_ptr2;
173
174  // Calculate input lengths and fill state.len with them.
175  // Test small lengths with more density than big ones. Manually push
176  // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
177  // Return number of lengths to test.
178  void InitLenArray() {
179    n = 0;
180    len[n++] = 0;
181    for (size_t i = 1; i < ITER; ++i) {
182      int l = (int) exp(log((double) MAX_LEN) * i / ITER);
183      if (l != len[n - 1]) {
184        len[n++] = l;
185      }
186    }
187    len[n++] = MAX_LEN;
188  }
189};
190
191TEST(string, strcat) {
192  StringTestState<char> state(SMALL);
193  for (size_t i = 1; i < state.n; i++) {
194    for (size_t j = 0; j < POS_ITER; j++) {
195      state.NewIteration();
196
197      memset(state.ptr2, '\2', state.MAX_LEN);
198      state.ptr2[state.MAX_LEN - 1] = '\0';
199      memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
200
201      memset(state.ptr1, random() & 255, state.len[i]);
202      state.ptr1[random() % state.len[i]] = '\0';
203      state.ptr1[state.len[i] - 1] = '\0';
204
205      strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
206
207      EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
208      EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
209    }
210  }
211}
212
213// one byte target with "\0" source
214TEST(string, strcpy2) {
215  char buf[1];
216  char* orig = strdup("");
217  strcpy(buf, orig);
218  ASSERT_EQ('\0', buf[0]);
219  free(orig);
220}
221
222// multibyte target where we under fill target
223TEST(string, strcpy3) {
224  char buf[10];
225  char* orig = strdup("12345");
226  memset(buf, 'A', sizeof(buf));
227  strcpy(buf, orig);
228  ASSERT_EQ('1',  buf[0]);
229  ASSERT_EQ('2',  buf[1]);
230  ASSERT_EQ('3',  buf[2]);
231  ASSERT_EQ('4',  buf[3]);
232  ASSERT_EQ('5',  buf[4]);
233  ASSERT_EQ('\0', buf[5]);
234  ASSERT_EQ('A',  buf[6]);
235  ASSERT_EQ('A',  buf[7]);
236  ASSERT_EQ('A',  buf[8]);
237  ASSERT_EQ('A',  buf[9]);
238  free(orig);
239}
240
241// multibyte target where we fill target exactly
242TEST(string, strcpy4) {
243  char buf[10];
244  char* orig = strdup("123456789");
245  memset(buf, 'A', sizeof(buf));
246  strcpy(buf, orig);
247  ASSERT_EQ('1',  buf[0]);
248  ASSERT_EQ('2',  buf[1]);
249  ASSERT_EQ('3',  buf[2]);
250  ASSERT_EQ('4',  buf[3]);
251  ASSERT_EQ('5',  buf[4]);
252  ASSERT_EQ('6',  buf[5]);
253  ASSERT_EQ('7',  buf[6]);
254  ASSERT_EQ('8',  buf[7]);
255  ASSERT_EQ('9',  buf[8]);
256  ASSERT_EQ('\0', buf[9]);
257  free(orig);
258}
259
260TEST(string, strcat2) {
261  char buf[10];
262  memset(buf, 'A', sizeof(buf));
263  buf[0] = 'a';
264  buf[1] = '\0';
265  char* res = strcat(buf, "01234");
266  ASSERT_EQ(buf, res);
267  ASSERT_EQ('a',  buf[0]);
268  ASSERT_EQ('0',  buf[1]);
269  ASSERT_EQ('1',  buf[2]);
270  ASSERT_EQ('2',  buf[3]);
271  ASSERT_EQ('3',  buf[4]);
272  ASSERT_EQ('4',  buf[5]);
273  ASSERT_EQ('\0', buf[6]);
274  ASSERT_EQ('A',  buf[7]);
275  ASSERT_EQ('A',  buf[8]);
276  ASSERT_EQ('A',  buf[9]);
277}
278
279TEST(string, strcat3) {
280  char buf[10];
281  memset(buf, 'A', sizeof(buf));
282  buf[0] = 'a';
283  buf[1] = '\0';
284  char* res = strcat(buf, "01234567");
285  ASSERT_EQ(buf, res);
286  ASSERT_EQ('a',  buf[0]);
287  ASSERT_EQ('0',  buf[1]);
288  ASSERT_EQ('1',  buf[2]);
289  ASSERT_EQ('2',  buf[3]);
290  ASSERT_EQ('3',  buf[4]);
291  ASSERT_EQ('4',  buf[5]);
292  ASSERT_EQ('5', buf[6]);
293  ASSERT_EQ('6',  buf[7]);
294  ASSERT_EQ('7',  buf[8]);
295  ASSERT_EQ('\0',  buf[9]);
296}
297
298TEST(string, strncat2) {
299  char buf[10];
300  memset(buf, 'A', sizeof(buf));
301  buf[0] = 'a';
302  buf[1] = '\0';
303  char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1);
304  ASSERT_EQ(buf, res);
305  ASSERT_EQ('a',  buf[0]);
306  ASSERT_EQ('0',  buf[1]);
307  ASSERT_EQ('1',  buf[2]);
308  ASSERT_EQ('2',  buf[3]);
309  ASSERT_EQ('3',  buf[4]);
310  ASSERT_EQ('4',  buf[5]);
311  ASSERT_EQ('\0', buf[6]);
312  ASSERT_EQ('A',  buf[7]);
313  ASSERT_EQ('A',  buf[8]);
314  ASSERT_EQ('A',  buf[9]);
315}
316
317TEST(string, strncat3) {
318  char buf[10];
319  memset(buf, 'A', sizeof(buf));
320  buf[0] = 'a';
321  buf[1] = '\0';
322  char* res = strncat(buf, "0123456789", 5);
323  ASSERT_EQ(buf, res);
324  ASSERT_EQ('a',  buf[0]);
325  ASSERT_EQ('0',  buf[1]);
326  ASSERT_EQ('1',  buf[2]);
327  ASSERT_EQ('2',  buf[3]);
328  ASSERT_EQ('3',  buf[4]);
329  ASSERT_EQ('4',  buf[5]);
330  ASSERT_EQ('\0', buf[6]);
331  ASSERT_EQ('A',  buf[7]);
332  ASSERT_EQ('A',  buf[8]);
333  ASSERT_EQ('A',  buf[9]);
334}
335
336TEST(string, strncat4) {
337  char buf[10];
338  memset(buf, 'A', sizeof(buf));
339  buf[0] = 'a';
340  buf[1] = '\0';
341  char* res = strncat(buf, "01234567", 8);
342  ASSERT_EQ(buf, res);
343  ASSERT_EQ('a',  buf[0]);
344  ASSERT_EQ('0',  buf[1]);
345  ASSERT_EQ('1',  buf[2]);
346  ASSERT_EQ('2',  buf[3]);
347  ASSERT_EQ('3',  buf[4]);
348  ASSERT_EQ('4',  buf[5]);
349  ASSERT_EQ('5', buf[6]);
350  ASSERT_EQ('6',  buf[7]);
351  ASSERT_EQ('7',  buf[8]);
352  ASSERT_EQ('\0',  buf[9]);
353}
354
355TEST(string, strncat5) {
356  char buf[10];
357  memset(buf, 'A', sizeof(buf));
358  buf[0] = 'a';
359  buf[1] = '\0';
360  char* res = strncat(buf, "01234567", 9);
361  ASSERT_EQ(buf, res);
362  ASSERT_EQ('a',  buf[0]);
363  ASSERT_EQ('0',  buf[1]);
364  ASSERT_EQ('1',  buf[2]);
365  ASSERT_EQ('2',  buf[3]);
366  ASSERT_EQ('3',  buf[4]);
367  ASSERT_EQ('4',  buf[5]);
368  ASSERT_EQ('5', buf[6]);
369  ASSERT_EQ('6',  buf[7]);
370  ASSERT_EQ('7',  buf[8]);
371  ASSERT_EQ('\0',  buf[9]);
372}
373
374TEST(string, strchr_with_0) {
375  char buf[10];
376  const char* s = "01234";
377  memcpy(buf, s, strlen(s) + 1);
378  EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
379}
380
381TEST(string, strchr) {
382  int seek_char = random() & 255;
383
384  StringTestState<char> state(SMALL);
385  for (size_t i = 1; i < state.n; i++) {
386    for (size_t j = 0; j < POS_ITER; j++) {
387      state.NewIteration();
388
389      if (~seek_char > 0) {
390        memset(state.ptr1, ~seek_char, state.len[i]);
391      } else {
392        memset(state.ptr1, '\1', state.len[i]);
393      }
394      state.ptr1[state.len[i] - 1] = '\0';
395
396      int pos = random() % state.MAX_LEN;
397      char* expected;
398      if (pos >= state.len[i] - 1) {
399        if (seek_char == 0) {
400          expected = state.ptr1 + state.len[i] - 1;
401        } else {
402          expected = NULL;
403        }
404      } else {
405        state.ptr1[pos] = seek_char;
406        expected = state.ptr1 + pos;
407      }
408
409      ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
410    }
411  }
412}
413
414TEST(string, strcmp) {
415  StringTestState<char> state(SMALL);
416  for (size_t i = 1; i < state.n; i++) {
417    for (size_t j = 0; j < POS_ITER; j++) {
418      state.NewIteration();
419
420      memset(state.ptr1, 'v', state.MAX_LEN);
421      memset(state.ptr2, 'n', state.MAX_LEN);
422      state.ptr1[state.len[i] - 1] = '\0';
423      state.ptr2[state.len[i] - 1] = '\0';
424
425      int pos = 1 + (random() % (state.MAX_LEN - 1));
426      int actual;
427      int expected;
428      if (pos >= state.len[i] - 1) {
429        memcpy(state.ptr1, state.ptr2, state.len[i]);
430        expected = 0;
431        actual = strcmp(state.ptr1, state.ptr2);
432      } else {
433        memcpy(state.ptr1, state.ptr2, pos);
434        if (state.ptr1[pos] > state.ptr2[pos]) {
435          expected = 1;
436        } else if (state.ptr1[pos] == state.ptr2[pos]) {
437          state.ptr1[pos + 1] = '\0';
438          state.ptr2[pos + 1] = '\0';
439          expected = 0;
440        } else {
441          expected = -1;
442        }
443        actual = strcmp(state.ptr1, state.ptr2);
444      }
445
446      ASSERT_EQ(expected, signum(actual));
447    }
448  }
449}
450
451TEST(string, strcpy) {
452  StringTestState<char> state(SMALL);
453  for (size_t j = 0; j < POS_ITER; j++) {
454    state.NewIteration();
455
456    size_t pos = random() % state.MAX_LEN;
457
458    memset(state.ptr1, '\2', pos);
459    state.ptr1[pos] = '\0';
460    state.ptr1[state.MAX_LEN - 1] = '\0';
461
462    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
463
464    memset(state.ptr2, '\1', state.MAX_LEN);
465    state.ptr2[state.MAX_LEN - 1] = '\0';
466
467    memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
468    memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
469    state.ptr[2 * state.MAX_LEN - 1] = '\0';
470
471    ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
472    ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
473                 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
474  }
475}
476
477
478#if __BIONIC__
479TEST(string, strlcat) {
480  StringTestState<char> state(SMALL);
481  for (size_t i = 0; i < state.n; i++) {
482    for (size_t j = 0; j < POS_ITER; j++) {
483      state.NewIteration();
484
485      memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
486      state.ptr2[state.MAX_LEN - 1] = '\0';
487      memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
488
489      int pos = random() % state.MAX_LEN;
490      memset(state.ptr1, '\3', pos);
491      state.ptr1[pos] = '\0';
492      if (pos < state.len[i]) {
493        memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
494      } else {
495        memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
496        state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
497      }
498
499      strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
500
501      ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
502    }
503  }
504}
505#endif
506
507#if __BIONIC__
508TEST(string, strlcpy) {
509  StringTestState<char> state(SMALL);
510  for (size_t j = 0; j < POS_ITER; j++) {
511    state.NewIteration();
512
513    int rand = random() & 255;
514    if (rand < 1) {
515      rand = 1;
516    }
517    memset(state.ptr1, rand, state.MAX_LEN);
518
519    size_t pos = random() % state.MAX_LEN;
520    if (pos < state.MAX_LEN) {
521      state.ptr1[pos] = '\0';
522    }
523    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
524
525    memset(state.ptr2, random() & 255, state.MAX_LEN);
526    memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
527
528    if (pos > state.MAX_LEN - 1) {
529      memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
530      state.ptr[2 * state.MAX_LEN - 1] = '\0';
531    } else {
532      memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
533    }
534
535    ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
536    ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
537                 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
538  }
539}
540#endif
541
542TEST(string, strncat) {
543  StringTestState<char> state(SMALL);
544  for (size_t i = 1; i < state.n; i++) {
545    for (size_t j = 0; j < POS_ITER; j++) {
546      state.NewIteration();
547
548      memset(state.ptr2, '\2', state.MAX_LEN);
549      state.ptr2[state.MAX_LEN - 1] = '\0';
550      memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
551
552      memset(state.ptr1, random() & 255, state.len[i]);
553      state.ptr1[random() % state.len[i]] = '\0';
554      state.ptr1[state.len[i] - 1] = '\0';
555
556      size_t pos = strlen(state.ptr1);
557
558      size_t actual = random() % state.len[i];
559      strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
560      state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
561
562      ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
563      ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
564    }
565  }
566}
567
568TEST(string, strncmp) {
569  StringTestState<char> state(SMALL);
570  for (size_t i = 1; i < state.n; i++) {
571    for (size_t j = 0; j < POS_ITER; j++) {
572      state.NewIteration();
573
574      memset(state.ptr1, 'v', state.MAX_LEN);
575      memset(state.ptr2, 'n', state.MAX_LEN);
576      state.ptr1[state.len[i] - 1] = '\0';
577      state.ptr2[state.len[i] - 1] = '\0';
578
579      int pos = 1 + (random() % (state.MAX_LEN - 1));
580      int actual;
581      int expected;
582      if (pos >= state.len[i] - 1) {
583        memcpy(state.ptr1, state.ptr2, state.len[i]);
584        expected = 0;
585        actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
586      } else {
587        memcpy(state.ptr1, state.ptr2, pos);
588        if (state.ptr1[pos] > state.ptr2[pos]) {
589          expected = 1;
590        } else if (state.ptr1[pos] == state.ptr2[pos]) {
591          state.ptr1[pos + 1] = '\0';
592          state.ptr2[pos + 1] = '\0';
593          expected = 0;
594        } else {
595          expected = -1;
596        }
597        actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
598      }
599
600      ASSERT_EQ(expected, signum(actual));
601    }
602  }
603}
604
605TEST(string, strncpy) {
606  StringTestState<char> state(SMALL);
607  for (size_t j = 0; j < ITER; j++) {
608    state.NewIteration();
609
610    memset(state.ptr1, random() & 255, state.MAX_LEN);
611    state.ptr1[random () % state.MAX_LEN] = '\0';
612    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
613
614    memset(state.ptr2, '\1', state.MAX_LEN);
615
616    size_t pos;
617    if (memchr(state.ptr1, 0, state.MAX_LEN)) {
618      pos = strlen(state.ptr1);
619    } else {
620      pos = state.MAX_LEN - 1;
621    }
622
623    memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN);
624    memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
625
626    ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2);
627    ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 ||
628                 memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0);
629  }
630}
631
632TEST(string, strrchr) {
633  int seek_char = random() & 255;
634  StringTestState<char> state(SMALL);
635  for (size_t i = 1; i < state.n; i++) {
636    for (size_t j = 0; j < POS_ITER; j++) {
637      state.NewIteration();
638
639      if (~seek_char > 0) {
640        memset(state.ptr1, ~seek_char, state.len[i]);
641      } else {
642        memset(state.ptr1, '\1', state.len[i]);
643      }
644      state.ptr1[state.len[i] - 1] = '\0';
645
646      int pos = random() % state.MAX_LEN;
647      char* expected;
648      if (pos >= state.len[i] - 1) {
649        if (seek_char == 0) {
650          expected = state.ptr1 + state.len[i] - 1;
651        } else {
652          expected = NULL;
653        }
654      } else {
655        state.ptr1[pos] = seek_char;
656        expected = state.ptr1 + pos;
657      }
658
659      ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
660    }
661  }
662}
663
664TEST(string, memchr) {
665  int seek_char = random() & 255;
666  StringTestState<char> state(SMALL);
667  for (size_t i = 0; i < state.n; i++) {
668    for (size_t j = 0; j < POS_ITER; j++) {
669      state.NewIteration();
670
671      memset(state.ptr1, ~seek_char, state.len[i]);
672
673      int pos = random() % state.MAX_LEN;
674      char* expected;
675      if (pos >= state.len[i]) {
676        expected = NULL;
677      } else {
678        state.ptr1[pos] = seek_char;
679        expected = state.ptr1 + pos;
680      }
681
682      ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
683    }
684  }
685}
686
687TEST(string, memrchr) {
688  int seek_char = random() & 255;
689  StringTestState<char> state(SMALL);
690  for (size_t i = 0; i < state.n; i++) {
691    for (size_t j = 0; j < POS_ITER; j++) {
692      state.NewIteration();
693
694      memset(state.ptr1, ~seek_char, state.len[i]);
695
696      int pos = random() % state.MAX_LEN;
697      char* expected;
698      if (pos >= state.len[i]) {
699        expected = NULL;
700      } else {
701        state.ptr1[pos] = seek_char;
702        expected = state.ptr1 + pos;
703      }
704
705      ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
706    }
707  }
708}
709
710TEST(string, memcmp) {
711  StringTestState<char> state(SMALL);
712  for (size_t i = 0; i < state.n; i++) {
713    for (size_t j = 0; j < POS_ITER; j++) {
714      state.NewIteration();
715
716      int c1 = random() & 0xff;
717      int c2 = random() & 0xff;
718      memset(state.ptr1, c1, state.MAX_LEN);
719      memset(state.ptr2, c1, state.MAX_LEN);
720
721      int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
722      state.ptr2[pos] = c2;
723
724      int expected = (static_cast<int>(c1) - static_cast<int>(c2));
725      int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
726
727      ASSERT_EQ(signum(expected), signum(actual));
728    }
729  }
730}
731
732#if defined(__BIONIC__)
733extern "C" int __memcmp16(const unsigned short *ptr1, const unsigned short *ptr2, size_t n);
734
735TEST(string, __memcmp16) {
736  StringTestState<unsigned short> state(SMALL);
737
738  for (size_t i = 0; i < state.n; i++) {
739    for (size_t j = 0; j < POS_ITER; j++) {
740      state.NewIteration();
741
742      unsigned short mask = 0xffff;
743      unsigned short c1 = rand() & mask;
744      unsigned short c2 = rand() & mask;
745
746      std::fill(state.ptr1, state.ptr1 + state.MAX_LEN, c1);
747      std::fill(state.ptr2, state.ptr2 + state.MAX_LEN, c1);
748
749      int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
750      state.ptr2[pos] = c2;
751
752      int expected = (static_cast<unsigned short>(c1) - static_cast<unsigned short>(c2));
753      int actual = __memcmp16(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
754
755      ASSERT_EQ(expected, actual);
756    }
757  }
758}
759#endif
760
761TEST(string, wmemcmp) {
762  StringTestState<wchar_t> state(SMALL);
763
764  for (size_t i = 0; i < state.n; i++) {
765    for (size_t j = 0; j < POS_ITER; j++) {
766      state.NewIteration();
767
768      long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1;
769      int c1 = rand() & mask;
770      int c2 = rand() & mask;
771      wmemset(state.ptr1, c1, state.MAX_LEN);
772      wmemset(state.ptr2, c1, state.MAX_LEN);
773
774      int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
775      state.ptr2[pos] = c2;
776
777      int expected = (static_cast<int>(c1) - static_cast<int>(c2));
778      int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
779
780      ASSERT_EQ(signum(expected), signum(actual));
781    }
782  }
783}
784
785TEST(string, memcpy) {
786  StringTestState<char> state(LARGE);
787  int rand = random() & 255;
788  for (size_t i = 0; i < state.n - 1; i++) {
789    for (size_t j = 0; j < POS_ITER; j++) {
790      state.NewIteration();
791
792      size_t pos = random() % (state.MAX_LEN - state.len[i]);
793
794      memset(state.ptr1, rand, state.len[i]);
795      memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
796
797      memset(state.ptr2, rand, state.len[i]);
798      memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
799      memset(state.ptr2 + pos, '\0', state.len[i]);
800
801      ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
802      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
803    }
804  }
805}
806
807TEST(string, memset) {
808  StringTestState<char> state(LARGE);
809  char ch = random () & 255;
810  for (size_t i = 0; i < state.n - 1; i++) {
811    for (size_t j = 0; j < POS_ITER; j++) {
812      state.NewIteration();
813
814      memset(state.ptr1, ~ch, state.MAX_LEN);
815      memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
816
817      size_t pos = random () % (state.MAX_LEN - state.len[i]);
818      for (size_t k = pos; k < pos + state.len[i]; k++) {
819        state.ptr1[k] = ch;
820      }
821
822      ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
823
824      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
825    }
826  }
827}
828
829TEST(string, memmove) {
830  StringTestState<char> state(LARGE);
831  for (size_t i = 0; i < state.n - 1; i++) {
832    for (size_t j = 0; j < POS_ITER; j++) {
833      state.NewIteration();
834
835      memset(state.ptr1, random() & 255, 2 * state.MAX_LEN);
836
837      size_t pos = random() % (state.MAX_LEN - state.len[i]);
838
839      memset(state.ptr1, random() & 255, state.len[i]);
840      memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
841      memcpy(state.ptr, state.ptr1, state.len[i]);
842      memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
843
844      ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
845      ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
846    }
847  }
848}
849
850TEST(string, bcopy) {
851  StringTestState<char> state(LARGE);
852  for (size_t i = 0; i < state.n; i++) {
853    for (size_t j = 0; j < POS_ITER; j++) {
854      state.NewIteration();
855
856      memset(state.ptr1, random() & 255, state.MAX_LEN);
857      memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN);
858      memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
859
860      size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
861      memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
862
863      bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
864      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
865    }
866  }
867}
868
869TEST(string, bzero) {
870  StringTestState<char> state(LARGE);
871  for (size_t j = 0; j < ITER; j++) {
872    state.NewIteration();
873
874    memset(state.ptr1, random() & 255, state.MAX_LEN);
875
876    size_t start = random() % state.MAX_LEN;
877    size_t end = start + random() % (state.MAX_LEN - start);
878
879    memcpy(state.ptr2, state.ptr1, start);
880    memset(state.ptr2 + start, '\0', end - start);
881    memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
882
883    bzero(state.ptr1 + start, end - start);
884
885    ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
886  }
887}
888