1b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea/*
2b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * Copyright (C) 2012 The Android Open Source Project
3b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea *
4b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * Licensed under the Apache License, Version 2.0 (the "License");
5b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * you may not use this file except in compliance with the License.
6b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * You may obtain a copy of the License at
7b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea *
8b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea *      http://www.apache.org/licenses/LICENSE-2.0
9b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea *
10b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * Unless required by applicable law or agreed to in writing, software
11b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * distributed under the License is distributed on an "AS IS" BASIS,
12b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * See the License for the specific language governing permissions and
14b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * limitations under the License.
15b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea */
16b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
17416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes#define _GNU_SOURCE 1
18416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes
1909c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes#include <string.h>
20b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
21b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea#include <errno.h>
2209c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes#include <gtest/gtest.h>
23e5fdaa4f9d102461a4d8a865e6ca84666893b9e7Dan Albert#include <malloc.h>
24036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova#include <math.h>
25d2a9fb326769900b786ef36aa0ccf60a65fe497eElliott Hughes#include <stdint.h>
26b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
2771766c25778fe13717259cdccb62463684794408Christopher Ferris#include <algorithm>
2871766c25778fe13717259cdccb62463684794408Christopher Ferris#include <vector>
2971766c25778fe13717259cdccb62463684794408Christopher Ferris
30b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris#include "buffer_tests.h"
31b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
3213f26a7b2bff5ed88b925b7206256e07596f3626Christopher Ferris#if defined(NOFORTIFY)
3313f26a7b2bff5ed88b925b7206256e07596f3626Christopher Ferris#define STRING_TEST string_nofortify
3413f26a7b2bff5ed88b925b7206256e07596f3626Christopher Ferris#else
3513f26a7b2bff5ed88b925b7206256e07596f3626Christopher Ferris#define STRING_TEST string
3613f26a7b2bff5ed88b925b7206256e07596f3626Christopher Ferris#endif
3713f26a7b2bff5ed88b925b7206256e07596f3626Christopher Ferris
381468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(__BIONIC__)
391468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#define STRLCPY_SUPPORTED
401468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#define STRLCAT_SUPPORTED
411468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
421468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
43d61ca37d35e31cae52a543e65d3ae02044abe5d3Chih-Hung Hsiehconstexpr auto KB = 1024;
44d61ca37d35e31cae52a543e65d3ae02044abe5d3Chih-Hung Hsiehconstexpr auto SMALL = 1 * KB;
45d61ca37d35e31cae52a543e65d3ae02044abe5d3Chih-Hung Hsiehconstexpr auto MEDIUM = 4 * KB;
46d61ca37d35e31cae52a543e65d3ae02044abe5d3Chih-Hung Hsiehconstexpr auto LARGE = 64 * KB;
47036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
48036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonovastatic int signum(int i) {
49036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  if (i < 0) {
50036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    return -1;
51036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  } else if (i > 0) {
52036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    return 1;
53036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
54036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  return 0;
55036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
56036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
5713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strerror) {
58b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  // Valid.
59b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Success", strerror(0));
60b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Operation not permitted", strerror(1));
61b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
62b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  // Invalid.
63e6e60065ff093ff8c859ab146cf543531cb1967cElliott Hughes  ASSERT_STREQ("Unknown error -1", strerror(-1));
64b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown error 1234", strerror(1234));
65b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea}
66b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
67f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__)
68ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughesstatic void* ConcurrentStrErrorFn(void*) {
69b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
70b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  return reinterpret_cast<void*>(equal);
71b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea}
72f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__
73b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
74f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris// glibc's strerror isn't thread safe, only its strsignal.
7513f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strerror_concurrent) {
76f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__)
77b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  const char* strerror1001 = strerror(1001);
78b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown error 1001", strerror1001);
79b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
80b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  pthread_t t;
81b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL));
82b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  void* result;
83b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_EQ(0, pthread_join(t, &result));
84b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_TRUE(static_cast<bool>(result));
85b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
86b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown error 1001", strerror1001);
87f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__
881468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  GTEST_LOG_(INFO) << "Skipping test, requires a thread safe strerror.";
89f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__
90b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea}
91ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughes
9213f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, gnu_strerror_r) {
93b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  char buf[256];
94b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
95416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  // Note that glibc doesn't necessarily write into the buffer.
96416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes
97b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  // Valid.
98416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  ASSERT_STREQ("Success", strerror_r(0, buf, sizeof(buf)));
99416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes#if defined(__BIONIC__)
100b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Success", buf);
101416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes#endif
102416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  ASSERT_STREQ("Operation not permitted", strerror_r(1, buf, sizeof(buf)));
103416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes#if defined(__BIONIC__)
104b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Operation not permitted", buf);
105416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes#endif
106b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
107b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  // Invalid.
108416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  ASSERT_STREQ("Unknown error -1", strerror_r(-1, buf, sizeof(buf)));
109606058933c5129cb1026960ea67624b9426c610fNick Kralevich  ASSERT_STREQ("Unknown error -1", buf);
110416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  ASSERT_STREQ("Unknown error 1234", strerror_r(1234, buf, sizeof(buf)));
111b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown error 1234", buf);
112b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
113b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  // Buffer too small.
114416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  errno = 0;
115416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  memset(buf, 0, sizeof(buf));
116416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  ASSERT_EQ(buf, strerror_r(4567, buf, 2));
117416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  ASSERT_STREQ("U", buf);
118416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  // The GNU strerror_r doesn't set errno (the POSIX one sets it to ERANGE).
119416d7ddaff0946d480b6aa945a741b3eeaca5569Elliott Hughes  ASSERT_EQ(0, errno);
120b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea}
121b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
12213f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strsignal) {
123b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  // A regular signal.
124b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Hangup", strsignal(1));
125b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
126b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  // A real-time signal.
1270990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes  ASSERT_STREQ("Real-time signal 14", strsignal(SIGRTMIN + 14));
1280990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes  // One of the signals the C library keeps to itself.
1290990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes  ASSERT_STREQ("Unknown signal 32", strsignal(__SIGRTMIN));
130b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
131b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  // Errors.
132b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
133b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small.
134b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large.
135b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea}
136b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
137ad88a0863110798cef5169dcf917e18b967a7cf6Elliott Hughesstatic void* ConcurrentStrSignalFn(void*) {
138b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
139b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  return reinterpret_cast<void*>(equal);
140b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea}
141b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
14213f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strsignal_concurrent) {
143b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  const char* strsignal1001 = strsignal(1001);
144b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown signal 1001", strsignal1001);
145b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
146b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  pthread_t t;
147b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL));
148b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  void* result;
149b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_EQ(0, pthread_join(t, &result));
150b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_TRUE(static_cast<bool>(result));
151b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea
152b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea  ASSERT_STREQ("Unknown signal 1001", strsignal1001);
153b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea}
154036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1551467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov// TODO: where did this number come from?
156036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova#define ITER        500
157036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
158036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova// For every length we want to test, vary and change alignment
159036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova// of allocated memory, fill it with some values, calculate
160036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova// expected result and then run function and compare what we got.
161036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova// These tests contributed by Intel Corporation.
162036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova// TODO: make these tests more intention-revealing and less random.
163baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenkotemplate<class Character>
1641467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanovclass StringTestState {
1651467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov public:
16662e3a078aa7b156139b1a2cec77e1a84eb10c5a4Chih-Hung Hsieh  explicit StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN), align1_index_(0), align2_index_(0) {
167036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    int max_alignment = 64;
168036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
169036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
170e5fdaa4f9d102461a4d8a865e6ca84666893b9e7Dan Albert    glob_ptr = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
171e5fdaa4f9d102461a4d8a865e6ca84666893b9e7Dan Albert    glob_ptr1 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
172e5fdaa4f9d102461a4d8a865e6ca84666893b9e7Dan Albert    glob_ptr2 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
173036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
174036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    InitLenArray();
175036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
176036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    srandom(1234);
177036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
178036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
179036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  ~StringTestState() {
180036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    free(glob_ptr);
181036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    free(glob_ptr1);
182036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    free(glob_ptr2);
183036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
184036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1851467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  void BeginIterations() {
1861467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    align1_index_ = 0;
1871467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    align2_index_ = 0;
188036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1891467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    ResetPointers();
1901467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  }
1911467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov
1921467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  bool HasNextIteration() {
1931467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    return (align1_index_ != (alignments_size - 1) || align2_index_ != (alignments_size - 1));
1941467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  }
1951467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov
1961467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  void NextIteration() {
1971467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    if (align1_index_ == (alignments_size - 1) && align2_index_ == (alignments_size - 1)) {
1981467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      return;
1991467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    }
2001467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov
2011467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    if (align1_index_ == (alignments_size - 1)) {
2021467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      align1_index_ = 0;
2031467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      align2_index_++;
2041467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    } else {
2051467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      align1_index_++;
2061467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    }
2071467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov
2081467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    ResetPointers();
209036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
210036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
211036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  const size_t MAX_LEN;
212baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  Character *ptr, *ptr1, *ptr2;
213036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  size_t n;
2147b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov  size_t len[ITER + 1];
215036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
216036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova private:
2171467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  static size_t alignments[];
2181467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  static size_t alignments_size;
219baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  Character *glob_ptr, *glob_ptr1, *glob_ptr2;
2201467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  size_t align1_index_, align2_index_;
221036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
222036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  // Calculate input lengths and fill state.len with them.
223036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  // Test small lengths with more density than big ones. Manually push
224036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
225036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  // Return number of lengths to test.
226036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  void InitLenArray() {
227036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    n = 0;
228036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    len[n++] = 0;
229036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    for (size_t i = 1; i < ITER; ++i) {
2307b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov      size_t l = static_cast<size_t>(exp(log(static_cast<double>(MAX_LEN)) * i / ITER));
231036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (l != len[n - 1]) {
232036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        len[n++] = l;
233036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
234036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
235036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    len[n++] = MAX_LEN;
236036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
2371467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov
2381467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  void ResetPointers() {
2391467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    if (align1_index_ == alignments_size || align2_index_ == alignments_size) {
2401467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      ptr = ptr1 = ptr2 = nullptr;
2411467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    } else {
2421467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      ptr = glob_ptr + alignments[align1_index_];
2431467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      ptr1 = glob_ptr1 + alignments[align1_index_];
2441467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      ptr2 = glob_ptr2 + alignments[align2_index_];
2451467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    }
2461467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  }
247036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova};
248036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
2491467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanovtemplate<class Character>
2501467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanovsize_t StringTestState<Character>::alignments[] = { 24, 32, 16, 48, 0, 1, 2, 3, 4, 5, 6, 7, 11 };
2511467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov
2521467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanovtemplate<class Character>
2531467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanovsize_t StringTestState<Character>::alignments_size = sizeof(alignments)/sizeof(size_t);
2541467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov
25513f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcat) {
256baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
257036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 1; i < state.n; i++) {
2581467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
259036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2, '\2', state.MAX_LEN);
260036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr2[state.MAX_LEN - 1] = '\0';
261036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
262036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
2631467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      memset(state.ptr1, 'L', state.len[i]);
264036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[random() % state.len[i]] = '\0';
265036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[state.len[i] - 1] = '\0';
266036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
267036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
268036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
269036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
270036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
271036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
272036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
273036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
274036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
27513476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich// one byte target with "\0" source
27613f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcpy2) {
27713476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  char buf[1];
27813476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  char* orig = strdup("");
279950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ(buf, strcpy(buf, orig));
28013476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  ASSERT_EQ('\0', buf[0]);
28113476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  free(orig);
28213476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich}
28313476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich
28413476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich// multibyte target where we under fill target
28513f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcpy3) {
28613476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  char buf[10];
28713476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  char* orig = strdup("12345");
28813476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  memset(buf, 'A', sizeof(buf));
289950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ(buf, strcpy(buf, orig));
290950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("12345", buf);
29113476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  ASSERT_EQ('A',  buf[6]);
29213476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  ASSERT_EQ('A',  buf[7]);
29313476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  ASSERT_EQ('A',  buf[8]);
29413476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  ASSERT_EQ('A',  buf[9]);
29513476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  free(orig);
29613476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich}
29713476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich
29813476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich// multibyte target where we fill target exactly
29913f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcpy4) {
30013476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  char buf[10];
30113476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  char* orig = strdup("123456789");
30213476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  memset(buf, 'A', sizeof(buf));
303950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ(buf, strcpy(buf, orig));
304950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("123456789", buf);
305950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  free(orig);
306950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris}
307950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
308950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris// one byte target with "\0" source
30913f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, stpcpy2) {
310950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  char buf[1];
311950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  char* orig = strdup("");
312950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ(buf, stpcpy(buf, orig));
313950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ('\0', buf[0]);
314950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  free(orig);
315950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris}
316950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
317950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris// multibyte target where we under fill target
31813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, stpcpy3) {
319950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  char buf[10];
320950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  char* orig = strdup("12345");
321950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  memset(buf, 'A', sizeof(buf));
322950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
323950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("12345", buf);
324950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ('A',  buf[6]);
325950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ('A',  buf[7]);
326950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ('A',  buf[8]);
327950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ('A',  buf[9]);
328950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  free(orig);
329950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris}
330950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
331950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris// multibyte target where we fill target exactly
33213f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, stpcpy4) {
333950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  char buf[10];
334950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  char* orig = strdup("123456789");
335950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  memset(buf, 'A', sizeof(buf));
336950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
337950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("123456789", buf);
33813476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich  free(orig);
33913476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich}
34013476deec46d7ba101c1f76b8ddcaab9d0b96b84Nick Kralevich
34113f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcat2) {
342cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char buf[10];
343cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  memset(buf, 'A', sizeof(buf));
344cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[0] = 'a';
345cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[1] = '\0';
346cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char* res = strcat(buf, "01234");
347cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ(buf, res);
348950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("a01234", buf);
349cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[7]);
350cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[8]);
351cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[9]);
352cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich}
353cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich
35413f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcat3) {
355cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char buf[10];
356cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  memset(buf, 'A', sizeof(buf));
357cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[0] = 'a';
358cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[1] = '\0';
359cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char* res = strcat(buf, "01234567");
360cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ(buf, res);
361950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("a01234567", buf);
362cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich}
363cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich
36413f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strncat2) {
365cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char buf[10];
366cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  memset(buf, 'A', sizeof(buf));
367cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[0] = 'a';
368cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[1] = '\0';
369cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1);
370cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ(buf, res);
371950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("a01234", buf);
372cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[7]);
373cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[8]);
374cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[9]);
375cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich}
376cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich
37713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strncat3) {
378cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char buf[10];
379cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  memset(buf, 'A', sizeof(buf));
380cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[0] = 'a';
381cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[1] = '\0';
382cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char* res = strncat(buf, "0123456789", 5);
383cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ(buf, res);
384950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("a01234", buf);
385cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[7]);
386cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[8]);
387cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ('A',  buf[9]);
388cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich}
389cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich
39013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strncat4) {
391cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char buf[10];
392cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  memset(buf, 'A', sizeof(buf));
393cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[0] = 'a';
394cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[1] = '\0';
395cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char* res = strncat(buf, "01234567", 8);
396cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ(buf, res);
397950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("a01234567", buf);
398cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich}
399cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich
40013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strncat5) {
401cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char buf[10];
402cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  memset(buf, 'A', sizeof(buf));
403cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[0] = 'a';
404cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  buf[1] = '\0';
405cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  char* res = strncat(buf, "01234567", 9);
406cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich  ASSERT_EQ(buf, res);
407950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  ASSERT_STREQ("a01234567", buf);
408cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich}
409cf870199d576bdfc339b7fb016c9f6fe7f2c87edNick Kralevich
41013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strchr_with_0) {
4114f40e511b0612ea099ab5b0843977fe7a49372fdNick Kralevich  char buf[10];
4124f40e511b0612ea099ab5b0843977fe7a49372fdNick Kralevich  const char* s = "01234";
4134f40e511b0612ea099ab5b0843977fe7a49372fdNick Kralevich  memcpy(buf, s, strlen(s) + 1);
4144f40e511b0612ea099ab5b0843977fe7a49372fdNick Kralevich  EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
4154f40e511b0612ea099ab5b0843977fe7a49372fdNick Kralevich}
4164f40e511b0612ea099ab5b0843977fe7a49372fdNick Kralevich
41713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strchr_multiple) {
4183a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  char str[128];
4193a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  memset(str, 'a', sizeof(str) - 1);
4203a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  str[sizeof(str)-1] = '\0';
4213a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris
4223a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  // Verify that strchr finds the first occurrence of 'a' in a string
4233a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  // filled with 'a' characters. Iterate over the string putting
4243a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  // non 'a' characters at the front of the string during each iteration
4253a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  // and continue to verify that strchr can find the first occurrence
4263a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  // properly. The idea is to cover all possible alignments of the location
4273a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  // of the first occurrence of the 'a' character and which includes
4283a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  // other 'a' characters close by.
4293a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  for (size_t i = 0; i < sizeof(str) - 1; i++) {
4303a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris    EXPECT_EQ(&str[i], strchr(str, 'a'));
4313a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris    str[i] = 'b';
4323a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  }
4333a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris}
4343a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris
43513f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strchr) {
4361467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  int seek_char = 'R';
437036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
438baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
439036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 1; i < state.n; i++) {
4401467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
441036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (~seek_char > 0) {
442036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memset(state.ptr1, ~seek_char, state.len[i]);
443036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
444036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memset(state.ptr1, '\1', state.len[i]);
445036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
446036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[state.len[i] - 1] = '\0';
447036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
4487b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov      size_t pos = random() % state.MAX_LEN;
449036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      char* expected;
450036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (pos >= state.len[i] - 1) {
451036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        if (seek_char == 0) {
452036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = state.ptr1 + state.len[i] - 1;
453036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        } else {
454036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = NULL;
455036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        }
456036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
457036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        state.ptr1[pos] = seek_char;
458036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        expected = state.ptr1 + pos;
459036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
460036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
461036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
462036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
463036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
464036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
465036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
46613f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strchrnul) {
4677ac3c128bb5df83cb001cb50b6a5ee4da9a0b0e0Elliott Hughes  const char* s = "01234222";
4687ac3c128bb5df83cb001cb50b6a5ee4da9a0b0e0Elliott Hughes  EXPECT_TRUE(strchrnul(s, '2') == &s[2]);
4697ac3c128bb5df83cb001cb50b6a5ee4da9a0b0e0Elliott Hughes  EXPECT_TRUE(strchrnul(s, '8') == (s + strlen(s)));
4707ac3c128bb5df83cb001cb50b6a5ee4da9a0b0e0Elliott Hughes  EXPECT_TRUE(strchrnul(s, '\0') == (s + strlen(s)));
4717ac3c128bb5df83cb001cb50b6a5ee4da9a0b0e0Elliott Hughes}
4727ac3c128bb5df83cb001cb50b6a5ee4da9a0b0e0Elliott Hughes
47313f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcmp) {
474baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
475036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 1; i < state.n; i++) {
4761467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
477036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1, 'v', state.MAX_LEN);
478036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2, 'n', state.MAX_LEN);
479036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[state.len[i] - 1] = '\0';
480036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr2[state.len[i] - 1] = '\0';
481036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
4827b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov      size_t pos = 1 + (random() % (state.MAX_LEN - 1));
483036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      int actual;
484036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      int expected;
485036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (pos >= state.len[i] - 1) {
486036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memcpy(state.ptr1, state.ptr2, state.len[i]);
487036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        expected = 0;
488036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        actual = strcmp(state.ptr1, state.ptr2);
489036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
490036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memcpy(state.ptr1, state.ptr2, pos);
491036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        if (state.ptr1[pos] > state.ptr2[pos]) {
492036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = 1;
493036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        } else if (state.ptr1[pos] == state.ptr2[pos]) {
494036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          state.ptr1[pos + 1] = '\0';
495036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          state.ptr2[pos + 1] = '\0';
496036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = 0;
497036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        } else {
498036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = -1;
499036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        }
500036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        actual = strcmp(state.ptr1, state.ptr2);
501036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
502036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
503036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_EQ(expected, signum(actual));
504036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
505036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
506036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
507036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
50813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, stpcpy) {
509950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  StringTestState<char> state(SMALL);
5101467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
511950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    size_t pos = random() % state.MAX_LEN;
512950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
513950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memset(state.ptr1, '\2', pos);
514950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    state.ptr1[pos] = '\0';
515950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    state.ptr1[state.MAX_LEN - 1] = '\0';
516950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
517950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
518950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
519950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memset(state.ptr2, '\1', state.MAX_LEN);
520950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    state.ptr2[state.MAX_LEN - 1] = '\0';
521950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
522950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
523950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
524950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    state.ptr[2 * state.MAX_LEN - 1] = '\0';
525950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
526950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_TRUE(stpcpy(state.ptr2, state.ptr1) == state.ptr2 + strlen(state.ptr1));
527950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
528950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris                 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
529950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  }
530950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris}
531950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
53213f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcpy) {
533baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
5341467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
535036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    size_t pos = random() % state.MAX_LEN;
536036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
537036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memset(state.ptr1, '\2', pos);
538036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    state.ptr1[pos] = '\0';
539036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    state.ptr1[state.MAX_LEN - 1] = '\0';
540036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
541036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
542036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
543036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memset(state.ptr2, '\1', state.MAX_LEN);
544036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    state.ptr2[state.MAX_LEN - 1] = '\0';
545036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
546036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
547036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
548036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    state.ptr[2 * state.MAX_LEN - 1] = '\0';
549036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
550036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
551036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
552036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova                 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
553036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
554036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
555036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
55613f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strlcat) {
5571468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(STRLCAT_SUPPORTED)
558baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
559036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 0; i < state.n; i++) {
5601467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
561036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
562036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr2[state.MAX_LEN - 1] = '\0';
563036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
564036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
5657b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov      size_t pos = random() % state.MAX_LEN;
566036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1, '\3', pos);
567036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[pos] = '\0';
568036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (pos < state.len[i]) {
569036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
570036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
571036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
572036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
573036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
574036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
575036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
576036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
577036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
578036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
579036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
5801468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#else
5811468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
5821468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
583036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
584036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
58513f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strlcpy) {
5861468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(STRLCPY_SUPPORTED)
587baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
5881467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
5891467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    int rand = 'O';
590036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memset(state.ptr1, rand, state.MAX_LEN);
591036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
592036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    size_t pos = random() % state.MAX_LEN;
593036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    if (pos < state.MAX_LEN) {
594036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[pos] = '\0';
595036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
596036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
597036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
5981467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    memset(state.ptr2, 'I', state.MAX_LEN);
599036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
600036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
601036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    if (pos > state.MAX_LEN - 1) {
602036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
603036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr[2 * state.MAX_LEN - 1] = '\0';
604036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    } else {
605036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
606036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
607036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
608036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
609036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
610036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova                 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
611036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
6121468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#else
6131468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
6141468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
615036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
616036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
61713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strncat) {
618baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
619036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 1; i < state.n; i++) {
6201467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
621036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2, '\2', state.MAX_LEN);
622036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr2[state.MAX_LEN - 1] = '\0';
623036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
624036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
6251467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      memset(state.ptr1, 'I', state.len[i]);
626036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[random() % state.len[i]] = '\0';
627036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[state.len[i] - 1] = '\0';
628036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
629036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      size_t pos = strlen(state.ptr1);
630036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
631036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      size_t actual = random() % state.len[i];
632036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
633036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
634036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
635036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
636036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
637036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
638036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
639036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
640036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
64113f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strncmp) {
642baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
643036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 1; i < state.n; i++) {
6441467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
645036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1, 'v', state.MAX_LEN);
646036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2, 'n', state.MAX_LEN);
647036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[state.len[i] - 1] = '\0';
648036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr2[state.len[i] - 1] = '\0';
649036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
6507b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov      size_t pos = 1 + (random() % (state.MAX_LEN - 1));
651036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      int actual;
652036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      int expected;
653036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (pos >= state.len[i] - 1) {
654036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memcpy(state.ptr1, state.ptr2, state.len[i]);
655036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        expected = 0;
656036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
657036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
658036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memcpy(state.ptr1, state.ptr2, pos);
659036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        if (state.ptr1[pos] > state.ptr2[pos]) {
660036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = 1;
661036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        } else if (state.ptr1[pos] == state.ptr2[pos]) {
662036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          state.ptr1[pos + 1] = '\0';
663036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          state.ptr2[pos + 1] = '\0';
664036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = 0;
665036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        } else {
666036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = -1;
667036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        }
668036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
669036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
670036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
671036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_EQ(expected, signum(actual));
672036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
673036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
674036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
675036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
67613f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, stpncpy) {
677baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
6781467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
6791467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    memset(state.ptr1, 'J', state.MAX_LEN);
680950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Choose a random size for our src buffer.
681950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    size_t ptr1_len = random() % state.MAX_LEN;
682950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    state.ptr1[ptr1_len] = '\0';
683950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
684036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
685950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Init ptr2 to a set value.
686950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memset(state.ptr2, '\1', state.MAX_LEN);
687036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
688950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Choose a random amount of data to copy.
689950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    size_t copy_len = random() % state.MAX_LEN;
690950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
691950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Set the second half of ptr to the expected pattern in ptr2.
692950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
693950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
694950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    size_t expected_end;
695950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    if (copy_len > ptr1_len) {
696950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris      memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
697950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris      expected_end = ptr1_len;
698950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    } else {
699950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris      expected_end = copy_len;
700950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    }
701950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
702950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
703950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
704950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Verify ptr1 was not modified.
705950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
706950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Verify ptr2 contains the expected data.
707950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
708950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  }
709950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris}
710950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
71113f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strncpy) {
712950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  StringTestState<char> state(SMALL);
7131467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
714950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Choose a random value to fill the string, except \0 (string terminator),
715950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // or \1 (guarantees it's different from anything in ptr2).
7161467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    memset(state.ptr1, 'K', state.MAX_LEN);
717950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Choose a random size for our src buffer.
718950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    size_t ptr1_len = random() % state.MAX_LEN;
719950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    state.ptr1[ptr1_len] = '\0';
720950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
721950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memcpy(state.ptr, state.ptr1, state.MAX_LEN);
722950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Init ptr2 to a set value.
723036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memset(state.ptr2, '\1', state.MAX_LEN);
724036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
725950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Choose a random amount of data to copy.
726950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    size_t copy_len = random() % state.MAX_LEN;
727950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
728950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Set the second half of ptr to the expected pattern in ptr2.
729950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
730950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
731950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    size_t expected_end;
732950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    if (copy_len > ptr1_len) {
733950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris      memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
734950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris      expected_end = ptr1_len;
735036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    } else {
736950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris      expected_end = copy_len;
737036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
738036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
739950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
740036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
741950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Verify ptr1 was not modified.
742950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
743950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    // Verify ptr2 contains the expected data.
744950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
745036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
746036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
747036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
74813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strrchr) {
7491467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  int seek_char = 'M';
750baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
751036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 1; i < state.n; i++) {
7521467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
753036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (~seek_char > 0) {
754036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memset(state.ptr1, ~seek_char, state.len[i]);
755036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
756036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        memset(state.ptr1, '\1', state.len[i]);
757036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
758036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr1[state.len[i] - 1] = '\0';
759036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
7607b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov      size_t pos = random() % state.MAX_LEN;
761036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      char* expected;
762036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (pos >= state.len[i] - 1) {
763036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        if (seek_char == 0) {
764036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = state.ptr1 + state.len[i] - 1;
765036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        } else {
766036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova          expected = NULL;
767036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        }
768036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
769036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        state.ptr1[pos] = seek_char;
770036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        expected = state.ptr1 + pos;
771036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
772036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
773036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
774036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
775036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
776036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
777036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
77813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memchr) {
7791467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  int seek_char = 'N';
780baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
781036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 0; i < state.n; i++) {
7821467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
783036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1, ~seek_char, state.len[i]);
784036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
7857b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov      size_t pos = random() % state.MAX_LEN;
786036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      char* expected;
787036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (pos >= state.len[i]) {
788036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        expected = NULL;
789036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
790036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        state.ptr1[pos] = seek_char;
791036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        expected = state.ptr1 + pos;
792036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
793036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
794036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
795036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
796036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
797036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
798036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
79913f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memchr_zero) {
800e03e1eac0b7682884b6628df1305d34299680cb4Christopher Ferris  uint8_t* buffer;
801e03e1eac0b7682884b6628df1305d34299680cb4Christopher Ferris  ASSERT_EQ(0, posix_memalign(reinterpret_cast<void**>(&buffer), 64, 64));
802e03e1eac0b7682884b6628df1305d34299680cb4Christopher Ferris  memset(buffer, 10, 64);
803e03e1eac0b7682884b6628df1305d34299680cb4Christopher Ferris  ASSERT_TRUE(NULL == memchr(buffer, 5, 0));
804e03e1eac0b7682884b6628df1305d34299680cb4Christopher Ferris  ASSERT_TRUE(NULL == memchr(buffer, 10, 0));
805e03e1eac0b7682884b6628df1305d34299680cb4Christopher Ferris}
806e03e1eac0b7682884b6628df1305d34299680cb4Christopher Ferris
80713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memrchr) {
8081467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  int seek_char = 'P';
809baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
810036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 0; i < state.n; i++) {
8111467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
812036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1, ~seek_char, state.len[i]);
813036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
8147b956ede3f0f40bd8a085a8ad3729bb3e0e030f2Dmitriy Ivanov      size_t pos = random() % state.MAX_LEN;
815036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      char* expected;
816036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      if (pos >= state.len[i]) {
817036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        expected = NULL;
818036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      } else {
819036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        state.ptr1[pos] = seek_char;
820036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        expected = state.ptr1 + pos;
821036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
822036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
823036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
824036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
825036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
826036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
827036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
82813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memcmp) {
829baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(SMALL);
830036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 0; i < state.n; i++) {
8311467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
8321467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      int c1 = 'A';
8331467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      int c2 = 'N';
834036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1, c1, state.MAX_LEN);
835036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2, c1, state.MAX_LEN);
836036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
837036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
838036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      state.ptr2[pos] = c2;
839036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
840036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      int expected = (static_cast<int>(c1) - static_cast<int>(c2));
841036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
842036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
843036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_EQ(signum(expected), signum(actual));
844036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
845036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
846036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
847036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
84813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, wmemcmp) {
849baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<wchar_t> state(SMALL);
850baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko
851baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  for (size_t i = 0; i < state.n; i++) {
8521467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
853baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1;
854baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      int c1 = rand() & mask;
855baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      int c2 = rand() & mask;
856baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      wmemset(state.ptr1, c1, state.MAX_LEN);
857baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      wmemset(state.ptr2, c1, state.MAX_LEN);
858baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko
859baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
860baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      state.ptr2[pos] = c2;
861baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko
862baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      int expected = (static_cast<int>(c1) - static_cast<int>(c2));
863baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
864baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko
865baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko      ASSERT_EQ(signum(expected), signum(actual));
866baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko    }
867baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  }
868baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko}
869baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko
87013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memcpy) {
871baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(LARGE);
8721467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  int rand = 4;
873036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 0; i < state.n - 1; i++) {
8741467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
875036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      size_t pos = random() % (state.MAX_LEN - state.len[i]);
876036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
877036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1, rand, state.len[i]);
878036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
879036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
880036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2, rand, state.len[i]);
881036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
882036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr2 + pos, '\0', state.len[i]);
883036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
884036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
885036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
886036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
887036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
888036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
889036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
89013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memset) {
891baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(LARGE);
8921467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  char ch = 'P';
893036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 0; i < state.n - 1; i++) {
8941467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
895036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memset(state.ptr1, ~ch, state.MAX_LEN);
896036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
897036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
898036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      size_t pos = random () % (state.MAX_LEN - state.len[i]);
899036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      for (size_t k = pos; k < pos + state.len[i]; k++) {
900036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova        state.ptr1[k] = ch;
901036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      }
902036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
903036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
904036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
905036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
906036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
907036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
908036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
909036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
91013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memmove) {
911baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(LARGE);
912036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 0; i < state.n - 1; i++) {
9131467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
9141467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      memset(state.ptr1, 'Q', 2 * state.MAX_LEN);
915036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
916036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      size_t pos = random() % (state.MAX_LEN - state.len[i]);
917036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
9181467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      memset(state.ptr1, 'R', state.len[i]);
919036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
920036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr, state.ptr1, state.len[i]);
921036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
922036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
923036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
924036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
925036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
926036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
927036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
928036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
92913f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memmove_cache_size) {
930fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  size_t len = 600000;
931fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  int max_alignment = 31;
932fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  int alignments[] = {0, 5, 11, 29, 30};
933fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  char* ptr = reinterpret_cast<char*>(malloc(sizeof(char) * len));
934fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  char* ptr1 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len));
935fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  char* glob_ptr2 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len + max_alignment));
936fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  size_t pos = 64;
937fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik
938fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  ASSERT_TRUE(ptr != NULL);
939fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  ASSERT_TRUE(ptr1 != NULL);
940fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  ASSERT_TRUE(glob_ptr2 != NULL);
941fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik
942fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  for (int i = 0; i < 5; i++) {
943fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik    char* ptr2 = glob_ptr2 + alignments[i];
9441467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    memset(ptr1, 'S', 2 * len);
9451467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    memset(ptr1, 'T', len);
946fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik    memcpy(ptr2, ptr1, 2 * len);
947fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik    memcpy(ptr, ptr1, len);
948fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik    memcpy(ptr1 + pos, ptr, len);
949fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik
950fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik    ASSERT_TRUE(memmove(ptr2 + pos, ptr, len) == ptr2 + pos);
951fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik    ASSERT_EQ(0, memcmp(ptr2, ptr1, 2 * len));
952fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  }
953fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  free(ptr);
954fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  free(ptr1);
955fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik  free(glob_ptr2);
956fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik}
957fce861498c8c4720c6ad2475a73bb4c3e55d6948Varvara Rainchik
9586c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhangstatic void verify_memmove(char* src_copy, char* dst, char* src, size_t size) {
9596c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  memset(dst, 0, size);
9606c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  memcpy(src, src_copy, size);
9616c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  ASSERT_EQ(dst, memmove(dst, src, size));
9626c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  ASSERT_EQ(0, memcmp(dst, src_copy, size));
9636c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang}
9646c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
9656c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang#define MEMMOVE_DATA_SIZE (1024*1024*3)
9666c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
96713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memmove_check) {
9686c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
9696c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  ASSERT_TRUE(buffer != NULL);
9706c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
9716c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  char* src_data = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
9726c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  ASSERT_TRUE(src_data != NULL);
9736c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  // Initialize to a known pattern to copy into src for each test and
9746c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  // to compare dst against.
9756c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  for (size_t i = 0; i < MEMMOVE_DATA_SIZE; i++) {
9766c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    src_data[i] = (i + 1) % 255;
9776c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  }
9786c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
9796c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  // Check all different dst offsets between 0 and 127 inclusive.
9806c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  char* src = buffer;
9816c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  for (size_t i = 0; i < 127; i++) {
9826c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    char* dst = buffer + 256 + i;
9836c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    // Small copy.
9846c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    verify_memmove(src_data, dst, src, 1024);
9856c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
9866c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    // Medium copy.
9876c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    verify_memmove(src_data, dst, src, 64 * 1024);
9886c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
9896c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    // Medium copy.
9906c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
9916c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  }
9926c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
9936c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  // Check all leftover size offsets between 1 and 127 inclusive.
9946c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  char* dst = buffer + 256;
9956c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  src = buffer;
9966c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  for (size_t size = 1; size < 127; size++) {
9976c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    // Small copy.
9986c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    verify_memmove(src_data, dst, src, 1024);
9996c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
10006c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    // Medium copy.
10016c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    verify_memmove(src_data, dst, src, 64 * 1024);
10026c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
10036c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    // Large copy.
10046c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang    verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
10056c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  }
10066c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang}
10076c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
100813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, bcopy) {
1009baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(LARGE);
1010036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  for (size_t i = 0; i < state.n; i++) {
10111467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
10121467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      memset(state.ptr1, '4', state.MAX_LEN);
10131467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov      memset(state.ptr1 + state.MAX_LEN, 'a', state.MAX_LEN);
1014036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
1015036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1016036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
1017036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
1018036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1019036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
1020036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova      ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
1021036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    }
1022036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
1023036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
1024036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
102513f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, bzero) {
1026baa91f4f8974b6e9a81fa3aa49f051b3bf823653Alexander Ivchenko  StringTestState<char> state(LARGE);
10271467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov  for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
10281467dfe3e89975f0d4905e31a27ac06257c097cfDmitriy Ivanov    memset(state.ptr1, 'R', state.MAX_LEN);
1029036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1030036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    size_t start = random() % state.MAX_LEN;
1031036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    size_t end = start + random() % (state.MAX_LEN - start);
1032036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1033036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memcpy(state.ptr2, state.ptr1, start);
1034036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memset(state.ptr2 + start, '\0', end - start);
1035036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
1036036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1037036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    bzero(state.ptr1 + start, end - start);
1038036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova
1039036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova    ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
1040036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova  }
1041036154b0c2d64d618aded8674f2e13cbbb2867e2Anna Tikhonova}
1042b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
1043b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferrisstatic void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1044b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  memset(src, (len % 255) + 1, len);
1045b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  memset(dst, 0, len);
1046b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
1047b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  ASSERT_EQ(dst, memcpy(dst, src, len));
1048b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  ASSERT_TRUE(memcmp(src, dst, len) == 0);
1049b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1050b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
105113f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memcpy_align) {
1052b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
1053b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1054b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
105513f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memcpy_overread) {
1056b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  RunSrcDstBufferOverreadTest(DoMemcpyTest);
1057b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1058b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
10596c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhangstatic void DoMemmoveTest(uint8_t* src, uint8_t* dst, size_t len) {
10606c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  memset(src, (len % 255) + 1, len);
10616c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  memset(dst, 0, len);
10626c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
10636c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  ASSERT_EQ(dst, memmove(dst, src, len));
10646c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  ASSERT_TRUE(memcmp(src, dst, len) == 0);
10656c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang}
10666c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
106713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memmove_align) {
10686c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
10696c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang}
10706c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
107113f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memmove_overread) {
10726c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang  RunSrcDstBufferOverreadTest(DoMemmoveTest);
10736c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang}
10746c80ccdeed9d9b30e961f68229fe8171d79c5d14Shu Zhang
1075b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferrisstatic void DoMemsetTest(uint8_t* buf, size_t len) {
1076b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  for (size_t i = 0; i < len; i++) {
1077b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    buf[i] = 0;
1078b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  }
1079b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  int value = (len % 255) + 1;
1080b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  ASSERT_EQ(buf, memset(buf, value, len));
1081b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  for (size_t i = 0; i < len; i++) {
1082b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    ASSERT_EQ(value, buf[i]);
1083b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  }
1084b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1085b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
108613f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memset_align) {
1087b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  RunSingleBufferAlignTest(LARGE, DoMemsetTest);
1088b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1089b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
1090b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferrisstatic void DoStrlenTest(uint8_t* buf, size_t len) {
1091b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  if (len >= 1) {
1092b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    memset(buf, (32 + (len % 96)), len - 1);
1093b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    buf[len-1] = '\0';
1094b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf)));
1095b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  }
1096b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1097b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
109813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strlen_align) {
1099b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  RunSingleBufferAlignTest(LARGE, DoStrlenTest);
1100b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1101b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
110213f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strlen_overread) {
1103b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  RunSingleBufferOverreadTest(DoStrlenTest);
1104b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1105b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
1106b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferrisstatic void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1107b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  if (len >= 1) {
1108b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    memset(src, (32 + (len % 96)), len - 1);
1109b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    src[len-1] = '\0';
1110b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    memset(dst, 0, len);
1111b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst),
1112b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris                                                     reinterpret_cast<char*>(src))));
1113b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    ASSERT_TRUE(memcmp(src, dst, len) == 0);
1114b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  }
1115b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1116b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
111713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcpy_align) {
1118b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
1119b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1120b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
112113f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcpy_overread) {
1122b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  RunSrcDstBufferOverreadTest(DoStrcpyTest);
1123b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1124b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
11251468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(STRLCPY_SUPPORTED)
11261468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferrisstatic void DoStrlcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
11271468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  if (len >= 1) {
11281468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    memset(src, (32 + (len % 96)), len - 1);
11291468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    src[len-1] = '\0';
11301468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    memset(dst, 0, len);
11311468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    ASSERT_EQ(len-1, strlcpy(reinterpret_cast<char*>(dst),
11321468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris                             reinterpret_cast<char*>(src), len));
11331468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    ASSERT_TRUE(memcmp(src, dst, len) == 0);
11341468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  }
11351468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris}
11361468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
11371468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
113813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strlcpy_align) {
11391468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(STRLCPY_SUPPORTED)
11401468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  RunSrcDstBufferAlignTest(LARGE, DoStrlcpyTest);
11411468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#else
11421468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
11431468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
11441468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris}
11451468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
114613f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strlcpy_overread) {
11471468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(STRLCPY_SUPPORTED)
11481468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  RunSrcDstBufferOverreadTest(DoStrlcpyTest);
11491468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#else
11501468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
11511468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
11521468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris}
11531468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
11541468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
1155950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferrisstatic void DoStpcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1156950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  if (len >= 1) {
1157950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memset(src, (32 + (len % 96)), len - 1);
1158950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    src[len-1] = '\0';
1159950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    memset(dst, 0, len);
1160950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_EQ(dst+len-1, reinterpret_cast<uint8_t*>(stpcpy(reinterpret_cast<char*>(dst),
1161950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris                                                           reinterpret_cast<char*>(src))));
1162950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris    ASSERT_TRUE(memcmp(src, dst, len) == 0);
1163950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  }
1164950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris}
1165950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
116613f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, stpcpy_align) {
1167950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest);
1168950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris}
1169950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
117013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, stpcpy_overread) {
1171950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris  RunSrcDstBufferOverreadTest(DoStpcpyTest);
1172950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris}
1173950a58e24d1019eb9d814dbb16f111a6b61e3f23Christopher Ferris
1174b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris// Use our own incrementer to cut down on the total number of calls.
1175e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferrisstatic size_t LargeSetIncrement(size_t len) {
1176b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  if (len >= 4096) {
1177b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    return 4096;
1178b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  } else if (len >= 1024) {
1179b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    return 1024;
1180b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  } else if (len >= 256) {
1181b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    return 256;
1182b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  }
1183b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  return 1;
1184b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1185b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
1186fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris#define STRCAT_DST_LEN  64
1187b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
1188b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferrisstatic void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) {
1189b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  if (len >= 1) {
1190b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    int value = 32 + (len % 96);
1191b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    memset(src, value, len - 1);
1192b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    src[len-1] = '\0';
1193b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
1194b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    if (len >= STRCAT_DST_LEN) {
1195b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      // Create a small buffer for doing quick compares in each loop.
1196b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      uint8_t cmp_buf[STRCAT_DST_LEN];
1197b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      // Make sure dst string contains a different value then the src string.
1198b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      int value2 = 32 + (value + 2) % 96;
1199b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      memset(cmp_buf, value2, sizeof(cmp_buf));
1200b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
1201fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris      for (size_t i = 1; i <= STRCAT_DST_LEN;) {
1202b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris        memset(dst, value2, i-1);
1203b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris        memset(dst+i-1, 0, len-i);
1204b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris        src[len-i] = '\0';
1205b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris        ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
1206b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris                                                         reinterpret_cast<char*>(src))));
1207b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris        ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
1208b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris        ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
1209fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        // This is an expensive loop, so don't loop through every value,
1210fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        // get to a certain size and then start doubling.
1211fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        if (i < 16) {
1212fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris          i++;
1213fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        } else {
1214fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris          i <<= 1;
1215fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        }
1216b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      }
1217b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    } else {
1218b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      dst[0] = '\0';
1219b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
1220b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris                                                       reinterpret_cast<char*>(src))));
1221b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris      ASSERT_TRUE(memcmp(src, dst, len) == 0);
1222b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris    }
1223b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  }
1224b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1225b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
122613f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcat_align) {
1227e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement);
1228b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1229b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris
123013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcat_overread) {
1231b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris  RunSrcDstBufferOverreadTest(DoStrcatTest);
1232b687ad3c3491fffe22507cafc9347e10cbf6bd31Christopher Ferris}
1233e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
12341468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(STRLCAT_SUPPORTED)
12351468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferrisstatic void DoStrlcatTest(uint8_t* src, uint8_t* dst, size_t len) {
12361468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  if (len >= 1) {
12371468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    int value = 32 + (len % 96);
12381468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    memset(src, value, len - 1);
12391468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    src[len-1] = '\0';
12401468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
12411468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    if (len >= STRCAT_DST_LEN) {
12421468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      // Create a small buffer for doing quick compares in each loop.
12431468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      uint8_t cmp_buf[STRCAT_DST_LEN];
12441468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      // Make sure dst string contains a different value then the src string.
12451468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      int value2 = 32 + (value + 2) % 96;
12461468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      memset(cmp_buf, value2, sizeof(cmp_buf));
12471468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
1248fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris      for (size_t i = 1; i <= STRCAT_DST_LEN;) {
12491468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris        memset(dst, value2, i-1);
12501468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris        memset(dst+i-1, 0, len-i);
12511468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris        src[len-i] = '\0';
12521468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris        ASSERT_EQ(len-1, strlcat(reinterpret_cast<char*>(dst),
12531468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris                                 reinterpret_cast<char*>(src), len));
12541468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris        ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
12551468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris        ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
1256fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        // This is an expensive loop, so don't loop through every value,
1257fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        // get to a certain size and then start doubling.
1258fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        if (i < 16) {
1259fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris          i++;
1260fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        } else {
1261fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris          i <<= 1;
1262fdfcfce7c6392d32f95a9f776ecd13da205b906cChristopher Ferris        }
12631468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      }
12641468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    } else {
12651468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      dst[0] = '\0';
12661468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      ASSERT_EQ(len-1, strlcat(reinterpret_cast<char*>(dst),
12671468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris                               reinterpret_cast<char*>(src), len));
12681468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris      ASSERT_TRUE(memcmp(src, dst, len) == 0);
12691468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris    }
12701468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  }
12711468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris}
12721468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
12731468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
127413f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strlcat_align) {
12751468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(STRLCAT_SUPPORTED)
12761468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  RunSrcDstBufferAlignTest(MEDIUM, DoStrlcatTest, LargeSetIncrement);
12771468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#else
12781468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
12791468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
12801468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris}
12811468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
128213f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strlcat_overread) {
12831468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#if defined(STRLCAT_SUPPORTED)
12841468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  RunSrcDstBufferOverreadTest(DoStrlcatTest);
12851468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#else
12861468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris  GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
12871468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris#endif
12881468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris}
12891468765f8ab81ae9e32638d25c14e1f5dd35da2bChristopher Ferris
1290e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferrisstatic void DoStrcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
1291e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  if (len >= 1) {
1292e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    memset(buf1, (32 + (len % 96)), len - 1);
1293e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    buf1[len-1] = '\0';
1294e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    memset(buf2, (32 + (len % 96)), len - 1);
1295e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    buf2[len-1] = '\0';
1296e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    ASSERT_EQ(0, strcmp(reinterpret_cast<char*>(buf1),
1297e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris                        reinterpret_cast<char*>(buf2)));
1298e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  }
1299e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris}
1300e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
1301e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferrisstatic void DoStrcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
1302e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  // Do string length differences.
1303e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  int c = (32 + (len1 % 96));
1304e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  memset(buf1, c, len1 - 1);
1305e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  buf1[len1-1] = '\0';
1306e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  memset(buf2, c, len2 - 1);
1307e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  buf2[len2-1] = '\0';
1308e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1309e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris                      reinterpret_cast<char*>(buf2)));
1310e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
1311e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  // Do single character differences.
1312e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  size_t len;
1313e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  if (len1 > len2) {
1314e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    len = len2;
1315e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  } else {
1316e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    len = len1;
1317e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  }
1318e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  // Need at least a two character buffer to do this test.
1319e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  if (len > 1) {
1320e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    buf1[len-1] = '\0';
1321e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    buf2[len-1] = '\0';
1322e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    int diff_c = (c + 1) % 96;
1323e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
1324e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    buf1[len-2] = diff_c;
1325e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1326e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris                        reinterpret_cast<char*>(buf2)));
1327e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
1328e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    buf1[len-2] = c;
1329e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    buf2[len-2] = diff_c;
1330e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1331e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris                        reinterpret_cast<char*>(buf2)));
1332e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  }
1333e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris}
1334e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
133513f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcmp_align) {
1336e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement);
1337e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris}
1338e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
133913f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strcmp_overread) {
1340e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest);
1341e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris}
1342e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
1343e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferrisstatic void DoMemcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
1344e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  memset(buf1, len+1, len);
1345e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  memset(buf2, len+1, len);
1346e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  ASSERT_EQ(0, memcmp(buf1, buf2, len));
1347e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris}
1348e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
1349e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferrisstatic void DoMemcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
1350e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  size_t len;
1351e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  if (len1 > len2) {
1352e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    len = len2;
1353e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  } else {
1354e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris    len = len1;
1355e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  }
1356e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
1357e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  memset(buf1, len2+1, len);
1358e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  buf1[len-1] = len2;
1359e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  memset(buf2, len2+1, len);
1360e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  ASSERT_NE(0, memcmp(buf1, buf2, len));
1361e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
1362e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  buf1[len-1] = len2+1;
1363e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  buf2[len-1] = len2;
1364e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  ASSERT_NE(0, memcmp(buf1, buf2, len));
1365e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris}
1366e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
136713f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memcmp_align) {
1368e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement);
1369e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris}
1370e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris
137113f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, memcmp_overread) {
1372e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris  RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
1373e5bbb6b6ab662503f06ceb20fa841d2e558d596dChristopher Ferris}
13743a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris
13752f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferrisstatic void DoMemchrTest(uint8_t* buf, size_t len) {
13762f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris  if (len >= 1) {
13772f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    int value = len % 128;
13782f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    int search_value = (len % 128) + 1;
13792f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    memset(buf, value, len);
13802f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    // The buffer does not contain the search value.
13812f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    ASSERT_EQ(nullptr, memchr(buf, search_value, len));
13822f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    if (len >= 2) {
13832f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      buf[0] = search_value;
13842f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      // The search value is the first element in the buffer.
13852f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      ASSERT_EQ(&buf[0], memchr(buf, search_value, len));
13862f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
13872f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      buf[0] = value;
13882f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      buf[len - 1] = search_value;
13892f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      // The search value is the last element in the buffer.
13902f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      ASSERT_EQ(&buf[len - 1], memchr(buf, search_value, len));
13912f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    }
13922f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris  }
13932f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris}
13942f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
13952f030af250c92198ea2785b6f71b48611228bbeaChristopher FerrisTEST(STRING_TEST, memchr_align) {
13962f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris  RunSingleBufferAlignTest(MEDIUM, DoMemchrTest);
13972f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris}
13982f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
13992f030af250c92198ea2785b6f71b48611228bbeaChristopher FerrisTEST(STRING_TEST, memchr_overread) {
14002f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris  RunSingleBufferOverreadTest(DoMemchrTest);
14012f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris}
14022f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
14033a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferrisstatic void DoStrchrTest(uint8_t* buf, size_t len) {
14043a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  if (len >= 1) {
14053a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris    char value = 32 + (len % 96);
14063a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris    char search_value = 33 + (len % 96);
14073a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris    memset(buf, value, len - 1);
14082f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    buf[len - 1] = '\0';
14092f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    // The buffer does not contain the search value.
14102f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    ASSERT_EQ(nullptr, strchr(reinterpret_cast<char*>(buf), search_value));
14112f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    // Search for the special '\0' character.
14122f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 1]), strchr(reinterpret_cast<char*>(buf), '\0'));
14133a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris    if (len >= 2) {
14143a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris      buf[0] = search_value;
14152f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      // The search value is the first element in the buffer.
14162f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strchr(reinterpret_cast<char*>(buf),
14172f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris                                                         search_value));
14182f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
14193a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris      buf[0] = value;
14202f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      buf[len - 2] = search_value;
14212f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      // The search value is the second to last element in the buffer.
14222f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      // The last element is the '\0' character.
14232f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 2]), strchr(reinterpret_cast<char*>(buf),
14242f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris                                                               search_value));
14253a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris    }
14263a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  }
14273a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris}
14283a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris
142913f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strchr_align) {
14303a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  RunSingleBufferAlignTest(MEDIUM, DoStrchrTest);
14313a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris}
14323a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris
143313f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strchr_overread) {
14343a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris  RunSingleBufferOverreadTest(DoStrchrTest);
14353a657d01eca1529ba7002cbee44e149988834c9dChristopher Ferris}
143609c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes
14372f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferrisstatic void DoStrrchrTest(uint8_t* buf, size_t len) {
14382f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris  if (len >= 1) {
14392f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    char value = 32 + (len % 96);
14402f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    char search_value = 33 + (len % 96);
14412f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    memset(buf, value, len - 1);
14422f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    buf[len - 1] = '\0';
14432f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    // The buffer does not contain the search value.
14442f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    ASSERT_EQ(nullptr, strrchr(reinterpret_cast<char*>(buf), search_value));
14452f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    // Search for the special '\0' character.
14462f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 1]), strrchr(reinterpret_cast<char*>(buf), '\0'));
14472f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    if (len >= 2) {
14482f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      buf[0] = search_value;
14492f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      // The search value is the first element in the buffer.
14502f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strrchr(reinterpret_cast<char*>(buf),
14512f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris                                                          search_value));
14522f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
14532f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      buf[0] = value;
14542f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      buf[len - 2] = search_value;
14552f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      // The search value is the second to last element in the buffer.
14562f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      // The last element is the '\0' character.
14572f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris      ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 2]), strrchr(reinterpret_cast<char*>(buf),
14582f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris                                                                search_value));
14592f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris    }
14602f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris  }
14612f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris}
14622f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
14632f030af250c92198ea2785b6f71b48611228bbeaChristopher FerrisTEST(STRING_TEST, strrchr_align) {
14642f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris  RunSingleBufferAlignTest(MEDIUM, DoStrrchrTest);
14652f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris}
14662f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
14672f030af250c92198ea2785b6f71b48611228bbeaChristopher FerrisTEST(STRING_TEST, strrchr_overread) {
14682f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris  RunSingleBufferOverreadTest(DoStrrchrTest);
14692f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris}
14702f030af250c92198ea2785b6f71b48611228bbeaChristopher Ferris
147109c39d6df0e952620f8c1751377b559a04e023aaElliott Hughesstatic void TestBasename(const char* in, const char* expected_out) {
147209c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  errno = 0;
147309c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  const char* out = basename(in);
147409c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  ASSERT_STREQ(expected_out, out) << in;
147509c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  ASSERT_EQ(0, errno) << in;
147609c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes}
147709c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes
147813f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, __gnu_basename) {
147909c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename("", "");
148009c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename("/usr/lib", "lib");
148109c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename("/usr/", "");
148209c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename("usr", "usr");
148309c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename("/", "");
148409c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename(".", ".");
148509c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename("..", "..");
148609c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename("///", "");
148709c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes  TestBasename("//usr//lib//", "");
148809c39d6df0e952620f8c1751377b559a04e023aaElliott Hughes}
148941ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes
149013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strnlen_147048) {
149141ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes  // https://code.google.com/p/android/issues/detail?id=147048
149241ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes  char stack_src[64] = {0};
149341ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes  EXPECT_EQ(0U, strnlen(stack_src, 1024*1024*1024));
149441ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes  char* heap_src = new char[1];
149541ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes  *heap_src = '\0';
149641ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes  EXPECT_EQ(0U, strnlen(heap_src, 1024*1024*1024));
149741ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes  delete[] heap_src;
149841ef902379ba24bd8a3ca6d7733b8376efb55ebdElliott Hughes}
14993cfb52aab2548df635e9672218cc433e14922fd3Elliott Hughes
150013f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, strnlen_74741) {
1501d2a9fb326769900b786ef36aa0ccf60a65fe497eElliott Hughes  ASSERT_EQ(4U, strnlen("test", SIZE_MAX));
1502d2a9fb326769900b786ef36aa0ccf60a65fe497eElliott Hughes}
1503d2a9fb326769900b786ef36aa0ccf60a65fe497eElliott Hughes
150413f26a7b2bff5ed88b925b7206256e07596f3626Christopher FerrisTEST(STRING_TEST, mempcpy) {
15053cfb52aab2548df635e9672218cc433e14922fd3Elliott Hughes  char dst[6];
15063cfb52aab2548df635e9672218cc433e14922fd3Elliott Hughes  ASSERT_EQ(&dst[4], reinterpret_cast<char*>(mempcpy(dst, "hello", 4)));
15073cfb52aab2548df635e9672218cc433e14922fd3Elliott Hughes}
150871766c25778fe13717259cdccb62463684794408Christopher Ferris
150971766c25778fe13717259cdccb62463684794408Christopher Ferris// clang depends on the fact that a memcpy where src and dst is the same
151071766c25778fe13717259cdccb62463684794408Christopher Ferris// still operates correctly. This test verifies that this assumption
151171766c25778fe13717259cdccb62463684794408Christopher Ferris// holds true.
151271766c25778fe13717259cdccb62463684794408Christopher Ferris// See https://llvm.org/bugs/show_bug.cgi?id=11763 for more information.
151371766c25778fe13717259cdccb62463684794408Christopher Ferrisstatic std::vector<uint8_t> g_memcpy_same_buffer;
151471766c25778fe13717259cdccb62463684794408Christopher Ferris
151571766c25778fe13717259cdccb62463684794408Christopher Ferrisstatic void DoMemcpySameTest(uint8_t* buffer, size_t len) {
151671766c25778fe13717259cdccb62463684794408Christopher Ferris  memcpy(buffer, g_memcpy_same_buffer.data(), len);
151771766c25778fe13717259cdccb62463684794408Christopher Ferris  ASSERT_EQ(buffer, memcpy(buffer, buffer, len));
151871766c25778fe13717259cdccb62463684794408Christopher Ferris  ASSERT_TRUE(memcmp(buffer, g_memcpy_same_buffer.data(), len) == 0);
151971766c25778fe13717259cdccb62463684794408Christopher Ferris}
152071766c25778fe13717259cdccb62463684794408Christopher Ferris
152171766c25778fe13717259cdccb62463684794408Christopher FerrisTEST(STRING_TEST, memcpy_src_dst_same) {
152271766c25778fe13717259cdccb62463684794408Christopher Ferris  g_memcpy_same_buffer.resize(MEDIUM);
152371766c25778fe13717259cdccb62463684794408Christopher Ferris  for (size_t i = 0; i < MEDIUM; i++) {
152471766c25778fe13717259cdccb62463684794408Christopher Ferris    g_memcpy_same_buffer[i] = i;
152571766c25778fe13717259cdccb62463684794408Christopher Ferris  }
152671766c25778fe13717259cdccb62463684794408Christopher Ferris  RunSingleBufferAlignTest(MEDIUM, DoMemcpySameTest);
152771766c25778fe13717259cdccb62463684794408Christopher Ferris}
1528cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes
1529cae33ade6c1300587db418f8d505b219b37503d6Elliott HughesTEST(STRING_TEST, memmem_strstr_empty_needle) {
1530cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  const char* some_haystack = "haystack";
1531cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  const char* empty_haystack = "";
1532cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes
1533cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(some_haystack, memmem(some_haystack, 8, "", 0));
1534cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(empty_haystack, memmem(empty_haystack, 0, "", 0));
1535cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes
1536cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(some_haystack, strstr(some_haystack, ""));
1537cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(empty_haystack, strstr(empty_haystack, ""));
1538cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes}
1539cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes
1540cae33ade6c1300587db418f8d505b219b37503d6Elliott HughesTEST(STRING_TEST, memmem_smoke) {
1541cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  const char haystack[] = "big\0daddy\0giant\0haystacks";
1542cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack, memmem(haystack, sizeof(haystack), "", 0));
1543cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack + 3, memmem(haystack, sizeof(haystack), "", 1));
1544cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "b", 1));
1545cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack + 1, memmem(haystack, sizeof(haystack), "i", 1));
1546cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack + 4, memmem(haystack, sizeof(haystack), "da", 2));
1547cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack + 8, memmem(haystack, sizeof(haystack), "y\0g", 3));
1548cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes}
1549cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes
1550cae33ade6c1300587db418f8d505b219b37503d6Elliott HughesTEST(STRING_TEST, strstr_smoke) {
1551cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  const char* haystack = "big daddy/giant haystacks";
1552cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack, strstr(haystack, ""));
1553cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack + 0, strstr(haystack, "b"));
1554cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack + 1, strstr(haystack, "i"));
1555cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes  ASSERT_EQ(haystack + 4, strstr(haystack, "da"));
1556cae33ade6c1300587db418f8d505b219b37503d6Elliott Hughes}
1557