1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker *
4*8d67ca89SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8d67ca89SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8d67ca89SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8d67ca89SAndroid Build Coastguard Worker *
8*8d67ca89SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8d67ca89SAndroid Build Coastguard Worker *
10*8d67ca89SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8d67ca89SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8d67ca89SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8d67ca89SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8d67ca89SAndroid Build Coastguard Worker * limitations under the License.
15*8d67ca89SAndroid Build Coastguard Worker */
16*8d67ca89SAndroid Build Coastguard Worker
17*8d67ca89SAndroid Build Coastguard Worker #define _GNU_SOURCE 1
18*8d67ca89SAndroid Build Coastguard Worker
19*8d67ca89SAndroid Build Coastguard Worker #include <string.h>
20*8d67ca89SAndroid Build Coastguard Worker
21*8d67ca89SAndroid Build Coastguard Worker #include <errno.h>
22*8d67ca89SAndroid Build Coastguard Worker #include <gtest/gtest.h>
23*8d67ca89SAndroid Build Coastguard Worker #include <malloc.h>
24*8d67ca89SAndroid Build Coastguard Worker #include <math.h>
25*8d67ca89SAndroid Build Coastguard Worker #include <stdint.h>
26*8d67ca89SAndroid Build Coastguard Worker #include <sys/cdefs.h>
27*8d67ca89SAndroid Build Coastguard Worker
28*8d67ca89SAndroid Build Coastguard Worker #include <algorithm>
29*8d67ca89SAndroid Build Coastguard Worker #include <vector>
30*8d67ca89SAndroid Build Coastguard Worker
31*8d67ca89SAndroid Build Coastguard Worker #include "buffer_tests.h"
32*8d67ca89SAndroid Build Coastguard Worker #include "utils.h"
33*8d67ca89SAndroid Build Coastguard Worker
34*8d67ca89SAndroid Build Coastguard Worker #if defined(NOFORTIFY)
35*8d67ca89SAndroid Build Coastguard Worker #define STRING_TEST string_nofortify
36*8d67ca89SAndroid Build Coastguard Worker #else
37*8d67ca89SAndroid Build Coastguard Worker #define STRING_TEST string
38*8d67ca89SAndroid Build Coastguard Worker #endif
39*8d67ca89SAndroid Build Coastguard Worker
40*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
41*8d67ca89SAndroid Build Coastguard Worker #define STRLCPY_SUPPORTED
42*8d67ca89SAndroid Build Coastguard Worker #define STRLCAT_SUPPORTED
43*8d67ca89SAndroid Build Coastguard Worker #endif
44*8d67ca89SAndroid Build Coastguard Worker
45*8d67ca89SAndroid Build Coastguard Worker constexpr auto KB = 1024;
46*8d67ca89SAndroid Build Coastguard Worker constexpr auto SMALL = 1 * KB;
47*8d67ca89SAndroid Build Coastguard Worker constexpr auto MEDIUM = 4 * KB;
48*8d67ca89SAndroid Build Coastguard Worker constexpr auto LARGE = 64 * KB;
49*8d67ca89SAndroid Build Coastguard Worker
signum(int i)50*8d67ca89SAndroid Build Coastguard Worker static int signum(int i) {
51*8d67ca89SAndroid Build Coastguard Worker if (i < 0) {
52*8d67ca89SAndroid Build Coastguard Worker return -1;
53*8d67ca89SAndroid Build Coastguard Worker } else if (i > 0) {
54*8d67ca89SAndroid Build Coastguard Worker return 1;
55*8d67ca89SAndroid Build Coastguard Worker }
56*8d67ca89SAndroid Build Coastguard Worker return 0;
57*8d67ca89SAndroid Build Coastguard Worker }
58*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strerror)59*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strerror) {
60*8d67ca89SAndroid Build Coastguard Worker // Valid.
61*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Success", strerror(0));
62*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Operation not permitted", strerror(1));
63*8d67ca89SAndroid Build Coastguard Worker
64*8d67ca89SAndroid Build Coastguard Worker // Invalid.
65*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown error -1", strerror(-1));
66*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown error 134", strerror(EHWPOISON + 1));
67*8d67ca89SAndroid Build Coastguard Worker }
68*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strerror_l)69*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strerror_l) {
70*8d67ca89SAndroid Build Coastguard Worker // bionic just forwards to strerror(3).
71*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Success", strerror_l(0, LC_GLOBAL_LOCALE));
72*8d67ca89SAndroid Build Coastguard Worker }
73*8d67ca89SAndroid Build Coastguard Worker
74*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
ConcurrentStrErrorFn(void *)75*8d67ca89SAndroid Build Coastguard Worker static void* ConcurrentStrErrorFn(void*) {
76*8d67ca89SAndroid Build Coastguard Worker bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
77*8d67ca89SAndroid Build Coastguard Worker return reinterpret_cast<void*>(equal);
78*8d67ca89SAndroid Build Coastguard Worker }
79*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
80*8d67ca89SAndroid Build Coastguard Worker
81*8d67ca89SAndroid Build Coastguard Worker // glibc's strerror isn't thread safe, only its strsignal.
TEST(STRING_TEST,strerror_concurrent)82*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strerror_concurrent) {
83*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
84*8d67ca89SAndroid Build Coastguard Worker const char* strerror1001 = strerror(1001);
85*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown error 1001", strerror1001);
86*8d67ca89SAndroid Build Coastguard Worker
87*8d67ca89SAndroid Build Coastguard Worker pthread_t t;
88*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_create(&t, nullptr, ConcurrentStrErrorFn, nullptr));
89*8d67ca89SAndroid Build Coastguard Worker void* result;
90*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_join(t, &result));
91*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(static_cast<bool>(result));
92*8d67ca89SAndroid Build Coastguard Worker
93*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown error 1001", strerror1001);
94*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
95*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "thread-safe strerror not available";
96*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
97*8d67ca89SAndroid Build Coastguard Worker }
98*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,gnu_strerror_r)99*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, gnu_strerror_r) {
100*8d67ca89SAndroid Build Coastguard Worker #if !defined(ANDROID_HOST_MUSL)
101*8d67ca89SAndroid Build Coastguard Worker char buf[256];
102*8d67ca89SAndroid Build Coastguard Worker
103*8d67ca89SAndroid Build Coastguard Worker // Note that glibc doesn't necessarily write into the buffer.
104*8d67ca89SAndroid Build Coastguard Worker
105*8d67ca89SAndroid Build Coastguard Worker // Valid.
106*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Success", strerror_r(0, buf, sizeof(buf)));
107*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
108*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Success", buf);
109*8d67ca89SAndroid Build Coastguard Worker #endif
110*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Operation not permitted", strerror_r(1, buf, sizeof(buf)));
111*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
112*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Operation not permitted", buf);
113*8d67ca89SAndroid Build Coastguard Worker #endif
114*8d67ca89SAndroid Build Coastguard Worker
115*8d67ca89SAndroid Build Coastguard Worker // Invalid.
116*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown error -1", strerror_r(-1, buf, sizeof(buf)));
117*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown error -1", buf);
118*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown error 1234", strerror_r(1234, buf, sizeof(buf)));
119*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown error 1234", buf);
120*8d67ca89SAndroid Build Coastguard Worker
121*8d67ca89SAndroid Build Coastguard Worker // Buffer too small.
122*8d67ca89SAndroid Build Coastguard Worker errno = 0;
123*8d67ca89SAndroid Build Coastguard Worker memset(buf, 0, sizeof(buf));
124*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, strerror_r(4567, buf, 2));
125*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("U", buf);
126*8d67ca89SAndroid Build Coastguard Worker // The GNU strerror_r doesn't set errno (the POSIX one sets it to ERANGE).
127*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(0);
128*8d67ca89SAndroid Build Coastguard Worker #else
129*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "musl doesn't have GNU strerror_r";
130*8d67ca89SAndroid Build Coastguard Worker #endif
131*8d67ca89SAndroid Build Coastguard Worker }
132*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strsignal)133*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strsignal) {
134*8d67ca89SAndroid Build Coastguard Worker // A regular signal.
135*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Hangup", strsignal(1));
136*8d67ca89SAndroid Build Coastguard Worker
137*8d67ca89SAndroid Build Coastguard Worker // A real-time signal.
138*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Real-time signal 14", strsignal(SIGRTMIN + 14));
139*8d67ca89SAndroid Build Coastguard Worker // One of the signals the C library keeps to itself.
140*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown signal 32", strsignal(32)); // __SIGRTMIN
141*8d67ca89SAndroid Build Coastguard Worker
142*8d67ca89SAndroid Build Coastguard Worker // Errors.
143*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
144*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small.
145*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large.
146*8d67ca89SAndroid Build Coastguard Worker }
147*8d67ca89SAndroid Build Coastguard Worker
ConcurrentStrSignalFn(void *)148*8d67ca89SAndroid Build Coastguard Worker static void* ConcurrentStrSignalFn(void*) {
149*8d67ca89SAndroid Build Coastguard Worker bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
150*8d67ca89SAndroid Build Coastguard Worker return reinterpret_cast<void*>(equal);
151*8d67ca89SAndroid Build Coastguard Worker }
152*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strsignal_concurrent)153*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strsignal_concurrent) {
154*8d67ca89SAndroid Build Coastguard Worker const char* strsignal1001 = strsignal(1001);
155*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown signal 1001", strsignal1001);
156*8d67ca89SAndroid Build Coastguard Worker
157*8d67ca89SAndroid Build Coastguard Worker pthread_t t;
158*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_create(&t, nullptr, ConcurrentStrSignalFn, nullptr));
159*8d67ca89SAndroid Build Coastguard Worker void* result;
160*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_join(t, &result));
161*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(static_cast<bool>(result));
162*8d67ca89SAndroid Build Coastguard Worker
163*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("Unknown signal 1001", strsignal1001);
164*8d67ca89SAndroid Build Coastguard Worker }
165*8d67ca89SAndroid Build Coastguard Worker
166*8d67ca89SAndroid Build Coastguard Worker // TODO: where did this number come from?
167*8d67ca89SAndroid Build Coastguard Worker #define ITER 500
168*8d67ca89SAndroid Build Coastguard Worker
169*8d67ca89SAndroid Build Coastguard Worker // For every length we want to test, vary and change alignment
170*8d67ca89SAndroid Build Coastguard Worker // of allocated memory, fill it with some values, calculate
171*8d67ca89SAndroid Build Coastguard Worker // expected result and then run function and compare what we got.
172*8d67ca89SAndroid Build Coastguard Worker // These tests contributed by Intel Corporation.
173*8d67ca89SAndroid Build Coastguard Worker // TODO: make these tests more intention-revealing and less random.
174*8d67ca89SAndroid Build Coastguard Worker template<class Character>
175*8d67ca89SAndroid Build Coastguard Worker class StringTestState {
176*8d67ca89SAndroid Build Coastguard Worker public:
StringTestState(size_t MAX_LEN)177*8d67ca89SAndroid Build Coastguard Worker explicit StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN), align1_index_(0), align2_index_(0) {
178*8d67ca89SAndroid Build Coastguard Worker int max_alignment = 64;
179*8d67ca89SAndroid Build Coastguard Worker
180*8d67ca89SAndroid Build Coastguard Worker // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
181*8d67ca89SAndroid Build Coastguard Worker glob_ptr = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
182*8d67ca89SAndroid Build Coastguard Worker glob_ptr1 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
183*8d67ca89SAndroid Build Coastguard Worker glob_ptr2 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
184*8d67ca89SAndroid Build Coastguard Worker
185*8d67ca89SAndroid Build Coastguard Worker InitLenArray();
186*8d67ca89SAndroid Build Coastguard Worker
187*8d67ca89SAndroid Build Coastguard Worker srandom(1234);
188*8d67ca89SAndroid Build Coastguard Worker }
189*8d67ca89SAndroid Build Coastguard Worker
~StringTestState()190*8d67ca89SAndroid Build Coastguard Worker ~StringTestState() {
191*8d67ca89SAndroid Build Coastguard Worker free(glob_ptr);
192*8d67ca89SAndroid Build Coastguard Worker free(glob_ptr1);
193*8d67ca89SAndroid Build Coastguard Worker free(glob_ptr2);
194*8d67ca89SAndroid Build Coastguard Worker }
195*8d67ca89SAndroid Build Coastguard Worker
BeginIterations()196*8d67ca89SAndroid Build Coastguard Worker void BeginIterations() {
197*8d67ca89SAndroid Build Coastguard Worker align1_index_ = 0;
198*8d67ca89SAndroid Build Coastguard Worker align2_index_ = 0;
199*8d67ca89SAndroid Build Coastguard Worker
200*8d67ca89SAndroid Build Coastguard Worker ResetPointers();
201*8d67ca89SAndroid Build Coastguard Worker }
202*8d67ca89SAndroid Build Coastguard Worker
HasNextIteration()203*8d67ca89SAndroid Build Coastguard Worker bool HasNextIteration() {
204*8d67ca89SAndroid Build Coastguard Worker return (align1_index_ != (alignments_size - 1) || align2_index_ != (alignments_size - 1));
205*8d67ca89SAndroid Build Coastguard Worker }
206*8d67ca89SAndroid Build Coastguard Worker
NextIteration()207*8d67ca89SAndroid Build Coastguard Worker void NextIteration() {
208*8d67ca89SAndroid Build Coastguard Worker if (align1_index_ == (alignments_size - 1) && align2_index_ == (alignments_size - 1)) {
209*8d67ca89SAndroid Build Coastguard Worker return;
210*8d67ca89SAndroid Build Coastguard Worker }
211*8d67ca89SAndroid Build Coastguard Worker
212*8d67ca89SAndroid Build Coastguard Worker if (align1_index_ == (alignments_size - 1)) {
213*8d67ca89SAndroid Build Coastguard Worker align1_index_ = 0;
214*8d67ca89SAndroid Build Coastguard Worker align2_index_++;
215*8d67ca89SAndroid Build Coastguard Worker } else {
216*8d67ca89SAndroid Build Coastguard Worker align1_index_++;
217*8d67ca89SAndroid Build Coastguard Worker }
218*8d67ca89SAndroid Build Coastguard Worker
219*8d67ca89SAndroid Build Coastguard Worker ResetPointers();
220*8d67ca89SAndroid Build Coastguard Worker }
221*8d67ca89SAndroid Build Coastguard Worker
222*8d67ca89SAndroid Build Coastguard Worker const size_t MAX_LEN;
223*8d67ca89SAndroid Build Coastguard Worker Character *ptr, *ptr1, *ptr2;
224*8d67ca89SAndroid Build Coastguard Worker size_t n;
225*8d67ca89SAndroid Build Coastguard Worker size_t len[ITER + 1];
226*8d67ca89SAndroid Build Coastguard Worker
227*8d67ca89SAndroid Build Coastguard Worker private:
228*8d67ca89SAndroid Build Coastguard Worker static size_t alignments[];
229*8d67ca89SAndroid Build Coastguard Worker static size_t alignments_size;
230*8d67ca89SAndroid Build Coastguard Worker Character *glob_ptr, *glob_ptr1, *glob_ptr2;
231*8d67ca89SAndroid Build Coastguard Worker size_t align1_index_, align2_index_;
232*8d67ca89SAndroid Build Coastguard Worker
233*8d67ca89SAndroid Build Coastguard Worker // Calculate input lengths and fill state.len with them.
234*8d67ca89SAndroid Build Coastguard Worker // Test small lengths with more density than big ones. Manually push
235*8d67ca89SAndroid Build Coastguard Worker // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
236*8d67ca89SAndroid Build Coastguard Worker // Return number of lengths to test.
InitLenArray()237*8d67ca89SAndroid Build Coastguard Worker void InitLenArray() {
238*8d67ca89SAndroid Build Coastguard Worker n = 0;
239*8d67ca89SAndroid Build Coastguard Worker len[n++] = 0;
240*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i < ITER; ++i) {
241*8d67ca89SAndroid Build Coastguard Worker size_t l = static_cast<size_t>(exp(log(static_cast<double>(MAX_LEN)) * i / ITER));
242*8d67ca89SAndroid Build Coastguard Worker if (l != len[n - 1]) {
243*8d67ca89SAndroid Build Coastguard Worker len[n++] = l;
244*8d67ca89SAndroid Build Coastguard Worker }
245*8d67ca89SAndroid Build Coastguard Worker }
246*8d67ca89SAndroid Build Coastguard Worker len[n++] = MAX_LEN;
247*8d67ca89SAndroid Build Coastguard Worker }
248*8d67ca89SAndroid Build Coastguard Worker
ResetPointers()249*8d67ca89SAndroid Build Coastguard Worker void ResetPointers() {
250*8d67ca89SAndroid Build Coastguard Worker if (align1_index_ == alignments_size || align2_index_ == alignments_size) {
251*8d67ca89SAndroid Build Coastguard Worker ptr = ptr1 = ptr2 = nullptr;
252*8d67ca89SAndroid Build Coastguard Worker } else {
253*8d67ca89SAndroid Build Coastguard Worker ptr = glob_ptr + alignments[align1_index_];
254*8d67ca89SAndroid Build Coastguard Worker ptr1 = glob_ptr1 + alignments[align1_index_];
255*8d67ca89SAndroid Build Coastguard Worker ptr2 = glob_ptr2 + alignments[align2_index_];
256*8d67ca89SAndroid Build Coastguard Worker }
257*8d67ca89SAndroid Build Coastguard Worker }
258*8d67ca89SAndroid Build Coastguard Worker };
259*8d67ca89SAndroid Build Coastguard Worker
260*8d67ca89SAndroid Build Coastguard Worker template<class Character>
261*8d67ca89SAndroid Build Coastguard Worker size_t StringTestState<Character>::alignments[] = { 24, 32, 16, 48, 0, 1, 2, 3, 4, 5, 6, 7, 11 };
262*8d67ca89SAndroid Build Coastguard Worker
263*8d67ca89SAndroid Build Coastguard Worker template<class Character>
264*8d67ca89SAndroid Build Coastguard Worker size_t StringTestState<Character>::alignments_size = sizeof(alignments)/sizeof(size_t);
265*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcat)266*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcat) {
267*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
268*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i < state.n; i++) {
269*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
270*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, '\2', state.MAX_LEN);
271*8d67ca89SAndroid Build Coastguard Worker state.ptr2[state.MAX_LEN - 1] = '\0';
272*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
273*8d67ca89SAndroid Build Coastguard Worker
274*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'L', state.len[i]);
275*8d67ca89SAndroid Build Coastguard Worker state.ptr1[random() % state.len[i]] = '\0';
276*8d67ca89SAndroid Build Coastguard Worker state.ptr1[state.len[i] - 1] = '\0';
277*8d67ca89SAndroid Build Coastguard Worker
278*8d67ca89SAndroid Build Coastguard Worker strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
279*8d67ca89SAndroid Build Coastguard Worker
280*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
281*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
282*8d67ca89SAndroid Build Coastguard Worker }
283*8d67ca89SAndroid Build Coastguard Worker }
284*8d67ca89SAndroid Build Coastguard Worker }
285*8d67ca89SAndroid Build Coastguard Worker
286*8d67ca89SAndroid Build Coastguard Worker // one byte target with "\0" source
TEST(STRING_TEST,strcpy2)287*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcpy2) {
288*8d67ca89SAndroid Build Coastguard Worker char buf[1];
289*8d67ca89SAndroid Build Coastguard Worker char* orig = strdup("");
290*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, strcpy(buf, orig));
291*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('\0', buf[0]);
292*8d67ca89SAndroid Build Coastguard Worker free(orig);
293*8d67ca89SAndroid Build Coastguard Worker }
294*8d67ca89SAndroid Build Coastguard Worker
295*8d67ca89SAndroid Build Coastguard Worker // multibyte target where we under fill target
TEST(STRING_TEST,strcpy3)296*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcpy3) {
297*8d67ca89SAndroid Build Coastguard Worker char buf[10];
298*8d67ca89SAndroid Build Coastguard Worker char* orig = strdup("12345");
299*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
300*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, strcpy(buf, orig));
301*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("12345", buf);
302*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[6]);
303*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[7]);
304*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[8]);
305*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[9]);
306*8d67ca89SAndroid Build Coastguard Worker free(orig);
307*8d67ca89SAndroid Build Coastguard Worker }
308*8d67ca89SAndroid Build Coastguard Worker
309*8d67ca89SAndroid Build Coastguard Worker // multibyte target where we fill target exactly
TEST(STRING_TEST,strcpy4)310*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcpy4) {
311*8d67ca89SAndroid Build Coastguard Worker char buf[10];
312*8d67ca89SAndroid Build Coastguard Worker char* orig = strdup("123456789");
313*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
314*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, strcpy(buf, orig));
315*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("123456789", buf);
316*8d67ca89SAndroid Build Coastguard Worker free(orig);
317*8d67ca89SAndroid Build Coastguard Worker }
318*8d67ca89SAndroid Build Coastguard Worker
319*8d67ca89SAndroid Build Coastguard Worker // one byte target with "\0" source
TEST(STRING_TEST,stpcpy2)320*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, stpcpy2) {
321*8d67ca89SAndroid Build Coastguard Worker char buf[1];
322*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
323*8d67ca89SAndroid Build Coastguard Worker char* orig = strdup("");
324*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(buf, stpcpy(buf, orig));
325*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ('\0', buf[0]);
326*8d67ca89SAndroid Build Coastguard Worker free(orig);
327*8d67ca89SAndroid Build Coastguard Worker }
328*8d67ca89SAndroid Build Coastguard Worker
329*8d67ca89SAndroid Build Coastguard Worker // multibyte target where we under fill target
TEST(STRING_TEST,stpcpy3)330*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, stpcpy3) {
331*8d67ca89SAndroid Build Coastguard Worker char buf[10];
332*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
333*8d67ca89SAndroid Build Coastguard Worker char* orig = strdup("12345");
334*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(buf+strlen(orig), stpcpy(buf, orig));
335*8d67ca89SAndroid Build Coastguard Worker EXPECT_STREQ("12345", buf);
336*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ('A', buf[6]);
337*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ('A', buf[7]);
338*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ('A', buf[8]);
339*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ('A', buf[9]);
340*8d67ca89SAndroid Build Coastguard Worker free(orig);
341*8d67ca89SAndroid Build Coastguard Worker }
342*8d67ca89SAndroid Build Coastguard Worker
343*8d67ca89SAndroid Build Coastguard Worker // multibyte target where we fill target exactly
TEST(STRING_TEST,stpcpy4)344*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, stpcpy4) {
345*8d67ca89SAndroid Build Coastguard Worker char buf[10];
346*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
347*8d67ca89SAndroid Build Coastguard Worker char* orig = strdup("123456789");
348*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(buf+strlen(orig), stpcpy(buf, orig));
349*8d67ca89SAndroid Build Coastguard Worker EXPECT_STREQ("123456789", buf);
350*8d67ca89SAndroid Build Coastguard Worker free(orig);
351*8d67ca89SAndroid Build Coastguard Worker }
352*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcat2)353*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcat2) {
354*8d67ca89SAndroid Build Coastguard Worker char buf[10];
355*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
356*8d67ca89SAndroid Build Coastguard Worker buf[0] = 'a';
357*8d67ca89SAndroid Build Coastguard Worker buf[1] = '\0';
358*8d67ca89SAndroid Build Coastguard Worker char* res = strcat(buf, "01234");
359*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, res);
360*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("a01234", buf);
361*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[7]);
362*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[8]);
363*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[9]);
364*8d67ca89SAndroid Build Coastguard Worker }
365*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcat3)366*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcat3) {
367*8d67ca89SAndroid Build Coastguard Worker char buf[10];
368*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
369*8d67ca89SAndroid Build Coastguard Worker buf[0] = 'a';
370*8d67ca89SAndroid Build Coastguard Worker buf[1] = '\0';
371*8d67ca89SAndroid Build Coastguard Worker char* res = strcat(buf, "01234567");
372*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, res);
373*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("a01234567", buf);
374*8d67ca89SAndroid Build Coastguard Worker }
375*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strncat2)376*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strncat2) {
377*8d67ca89SAndroid Build Coastguard Worker char buf[10];
378*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
379*8d67ca89SAndroid Build Coastguard Worker buf[0] = 'a';
380*8d67ca89SAndroid Build Coastguard Worker buf[1] = '\0';
381*8d67ca89SAndroid Build Coastguard Worker char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1);
382*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, res);
383*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("a01234", buf);
384*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[7]);
385*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[8]);
386*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[9]);
387*8d67ca89SAndroid Build Coastguard Worker }
388*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strncat3)389*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strncat3) {
390*8d67ca89SAndroid Build Coastguard Worker char buf[10];
391*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
392*8d67ca89SAndroid Build Coastguard Worker buf[0] = 'a';
393*8d67ca89SAndroid Build Coastguard Worker buf[1] = '\0';
394*8d67ca89SAndroid Build Coastguard Worker char* res = strncat(buf, "0123456789", 5);
395*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, res);
396*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("a01234", buf);
397*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[7]);
398*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[8]);
399*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ('A', buf[9]);
400*8d67ca89SAndroid Build Coastguard Worker }
401*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strncat4)402*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strncat4) {
403*8d67ca89SAndroid Build Coastguard Worker char buf[10];
404*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
405*8d67ca89SAndroid Build Coastguard Worker buf[0] = 'a';
406*8d67ca89SAndroid Build Coastguard Worker buf[1] = '\0';
407*8d67ca89SAndroid Build Coastguard Worker char* res = strncat(buf, "01234567", 8);
408*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, res);
409*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("a01234567", buf);
410*8d67ca89SAndroid Build Coastguard Worker }
411*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strncat5)412*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strncat5) {
413*8d67ca89SAndroid Build Coastguard Worker char buf[10];
414*8d67ca89SAndroid Build Coastguard Worker memset(buf, 'A', sizeof(buf));
415*8d67ca89SAndroid Build Coastguard Worker buf[0] = 'a';
416*8d67ca89SAndroid Build Coastguard Worker buf[1] = '\0';
417*8d67ca89SAndroid Build Coastguard Worker char* res = strncat(buf, "01234567", 9);
418*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, res);
419*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("a01234567", buf);
420*8d67ca89SAndroid Build Coastguard Worker }
421*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strchr_with_0)422*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strchr_with_0) {
423*8d67ca89SAndroid Build Coastguard Worker char buf[10];
424*8d67ca89SAndroid Build Coastguard Worker const char* s = "01234";
425*8d67ca89SAndroid Build Coastguard Worker memcpy(buf, s, strlen(s) + 1);
426*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
427*8d67ca89SAndroid Build Coastguard Worker }
428*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strchr_multiple)429*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strchr_multiple) {
430*8d67ca89SAndroid Build Coastguard Worker char str[128];
431*8d67ca89SAndroid Build Coastguard Worker memset(str, 'a', sizeof(str) - 1);
432*8d67ca89SAndroid Build Coastguard Worker str[sizeof(str)-1] = '\0';
433*8d67ca89SAndroid Build Coastguard Worker
434*8d67ca89SAndroid Build Coastguard Worker // Verify that strchr finds the first occurrence of 'a' in a string
435*8d67ca89SAndroid Build Coastguard Worker // filled with 'a' characters. Iterate over the string putting
436*8d67ca89SAndroid Build Coastguard Worker // non 'a' characters at the front of the string during each iteration
437*8d67ca89SAndroid Build Coastguard Worker // and continue to verify that strchr can find the first occurrence
438*8d67ca89SAndroid Build Coastguard Worker // properly. The idea is to cover all possible alignments of the location
439*8d67ca89SAndroid Build Coastguard Worker // of the first occurrence of the 'a' character and which includes
440*8d67ca89SAndroid Build Coastguard Worker // other 'a' characters close by.
441*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < sizeof(str) - 1; i++) {
442*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(&str[i], strchr(str, 'a'));
443*8d67ca89SAndroid Build Coastguard Worker str[i] = 'b';
444*8d67ca89SAndroid Build Coastguard Worker }
445*8d67ca89SAndroid Build Coastguard Worker }
446*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strchr)447*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strchr) {
448*8d67ca89SAndroid Build Coastguard Worker int seek_char = 'R';
449*8d67ca89SAndroid Build Coastguard Worker
450*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
451*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i < state.n; i++) {
452*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
453*8d67ca89SAndroid Build Coastguard Worker if (~seek_char > 0) {
454*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, ~seek_char, state.len[i]);
455*8d67ca89SAndroid Build Coastguard Worker } else {
456*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, '\1', state.len[i]);
457*8d67ca89SAndroid Build Coastguard Worker }
458*8d67ca89SAndroid Build Coastguard Worker state.ptr1[state.len[i] - 1] = '\0';
459*8d67ca89SAndroid Build Coastguard Worker
460*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % state.MAX_LEN;
461*8d67ca89SAndroid Build Coastguard Worker char* expected;
462*8d67ca89SAndroid Build Coastguard Worker if (pos >= state.len[i] - 1) {
463*8d67ca89SAndroid Build Coastguard Worker if (seek_char == 0) {
464*8d67ca89SAndroid Build Coastguard Worker expected = state.ptr1 + state.len[i] - 1;
465*8d67ca89SAndroid Build Coastguard Worker } else {
466*8d67ca89SAndroid Build Coastguard Worker expected = nullptr;
467*8d67ca89SAndroid Build Coastguard Worker }
468*8d67ca89SAndroid Build Coastguard Worker } else {
469*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos] = seek_char;
470*8d67ca89SAndroid Build Coastguard Worker expected = state.ptr1 + pos;
471*8d67ca89SAndroid Build Coastguard Worker }
472*8d67ca89SAndroid Build Coastguard Worker
473*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
474*8d67ca89SAndroid Build Coastguard Worker }
475*8d67ca89SAndroid Build Coastguard Worker }
476*8d67ca89SAndroid Build Coastguard Worker }
477*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strchrnul)478*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strchrnul) {
479*8d67ca89SAndroid Build Coastguard Worker const char* s = "01234222";
480*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(strchrnul(s, '2') == &s[2]);
481*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(strchrnul(s, '8') == (s + strlen(s)));
482*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(strchrnul(s, '\0') == (s + strlen(s)));
483*8d67ca89SAndroid Build Coastguard Worker }
484*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcmp)485*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcmp) {
486*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
487*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i < state.n; i++) {
488*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
489*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'v', state.MAX_LEN);
490*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, 'n', state.MAX_LEN);
491*8d67ca89SAndroid Build Coastguard Worker state.ptr1[state.len[i] - 1] = '\0';
492*8d67ca89SAndroid Build Coastguard Worker state.ptr2[state.len[i] - 1] = '\0';
493*8d67ca89SAndroid Build Coastguard Worker
494*8d67ca89SAndroid Build Coastguard Worker size_t pos = 1 + (random() % (state.MAX_LEN - 1));
495*8d67ca89SAndroid Build Coastguard Worker int actual;
496*8d67ca89SAndroid Build Coastguard Worker int expected;
497*8d67ca89SAndroid Build Coastguard Worker if (pos >= state.len[i] - 1) {
498*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr1, state.ptr2, state.len[i]);
499*8d67ca89SAndroid Build Coastguard Worker expected = 0;
500*8d67ca89SAndroid Build Coastguard Worker actual = strcmp(state.ptr1, state.ptr2);
501*8d67ca89SAndroid Build Coastguard Worker } else {
502*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr1, state.ptr2, pos);
503*8d67ca89SAndroid Build Coastguard Worker if (state.ptr1[pos] > state.ptr2[pos]) {
504*8d67ca89SAndroid Build Coastguard Worker expected = 1;
505*8d67ca89SAndroid Build Coastguard Worker } else if (state.ptr1[pos] == state.ptr2[pos]) {
506*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos + 1] = '\0';
507*8d67ca89SAndroid Build Coastguard Worker state.ptr2[pos + 1] = '\0';
508*8d67ca89SAndroid Build Coastguard Worker expected = 0;
509*8d67ca89SAndroid Build Coastguard Worker } else {
510*8d67ca89SAndroid Build Coastguard Worker expected = -1;
511*8d67ca89SAndroid Build Coastguard Worker }
512*8d67ca89SAndroid Build Coastguard Worker actual = strcmp(state.ptr1, state.ptr2);
513*8d67ca89SAndroid Build Coastguard Worker }
514*8d67ca89SAndroid Build Coastguard Worker
515*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(expected, signum(actual));
516*8d67ca89SAndroid Build Coastguard Worker }
517*8d67ca89SAndroid Build Coastguard Worker }
518*8d67ca89SAndroid Build Coastguard Worker }
519*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,stpcpy)520*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, stpcpy) {
521*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
522*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
523*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % state.MAX_LEN;
524*8d67ca89SAndroid Build Coastguard Worker
525*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, '\2', pos);
526*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos] = '\0';
527*8d67ca89SAndroid Build Coastguard Worker state.ptr1[state.MAX_LEN - 1] = '\0';
528*8d67ca89SAndroid Build Coastguard Worker
529*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr1, state.MAX_LEN);
530*8d67ca89SAndroid Build Coastguard Worker
531*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, '\1', state.MAX_LEN);
532*8d67ca89SAndroid Build Coastguard Worker state.ptr2[state.MAX_LEN - 1] = '\0';
533*8d67ca89SAndroid Build Coastguard Worker
534*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
535*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
536*8d67ca89SAndroid Build Coastguard Worker state.ptr[2 * state.MAX_LEN - 1] = '\0';
537*8d67ca89SAndroid Build Coastguard Worker
538*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(stpcpy(state.ptr2, state.ptr1) == state.ptr2 + strlen(state.ptr1));
539*8d67ca89SAndroid Build Coastguard Worker ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
540*8d67ca89SAndroid Build Coastguard Worker (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
541*8d67ca89SAndroid Build Coastguard Worker }
542*8d67ca89SAndroid Build Coastguard Worker }
543*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcpy)544*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcpy) {
545*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
546*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
547*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % state.MAX_LEN;
548*8d67ca89SAndroid Build Coastguard Worker
549*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, '\2', pos);
550*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos] = '\0';
551*8d67ca89SAndroid Build Coastguard Worker state.ptr1[state.MAX_LEN - 1] = '\0';
552*8d67ca89SAndroid Build Coastguard Worker
553*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr1, state.MAX_LEN);
554*8d67ca89SAndroid Build Coastguard Worker
555*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, '\1', state.MAX_LEN);
556*8d67ca89SAndroid Build Coastguard Worker state.ptr2[state.MAX_LEN - 1] = '\0';
557*8d67ca89SAndroid Build Coastguard Worker
558*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
559*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
560*8d67ca89SAndroid Build Coastguard Worker state.ptr[2 * state.MAX_LEN - 1] = '\0';
561*8d67ca89SAndroid Build Coastguard Worker
562*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
563*8d67ca89SAndroid Build Coastguard Worker ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
564*8d67ca89SAndroid Build Coastguard Worker (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
565*8d67ca89SAndroid Build Coastguard Worker }
566*8d67ca89SAndroid Build Coastguard Worker }
567*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strlcat)568*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strlcat) {
569*8d67ca89SAndroid Build Coastguard Worker #if defined(STRLCAT_SUPPORTED)
570*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
571*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n; i++) {
572*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
573*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
574*8d67ca89SAndroid Build Coastguard Worker state.ptr2[state.MAX_LEN - 1] = '\0';
575*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
576*8d67ca89SAndroid Build Coastguard Worker
577*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % state.MAX_LEN;
578*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, '\3', pos);
579*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos] = '\0';
580*8d67ca89SAndroid Build Coastguard Worker if (pos < state.len[i]) {
581*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
582*8d67ca89SAndroid Build Coastguard Worker } else {
583*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
584*8d67ca89SAndroid Build Coastguard Worker state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
585*8d67ca89SAndroid Build Coastguard Worker }
586*8d67ca89SAndroid Build Coastguard Worker
587*8d67ca89SAndroid Build Coastguard Worker strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
588*8d67ca89SAndroid Build Coastguard Worker
589*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
590*8d67ca89SAndroid Build Coastguard Worker }
591*8d67ca89SAndroid Build Coastguard Worker }
592*8d67ca89SAndroid Build Coastguard Worker #else
593*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "strlcat not available";
594*8d67ca89SAndroid Build Coastguard Worker #endif
595*8d67ca89SAndroid Build Coastguard Worker }
596*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strlcpy)597*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strlcpy) {
598*8d67ca89SAndroid Build Coastguard Worker #if defined(STRLCPY_SUPPORTED)
599*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
600*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
601*8d67ca89SAndroid Build Coastguard Worker int rand = 'O';
602*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, rand, state.MAX_LEN);
603*8d67ca89SAndroid Build Coastguard Worker
604*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % state.MAX_LEN;
605*8d67ca89SAndroid Build Coastguard Worker if (pos < state.MAX_LEN) {
606*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos] = '\0';
607*8d67ca89SAndroid Build Coastguard Worker }
608*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr1, state.MAX_LEN);
609*8d67ca89SAndroid Build Coastguard Worker
610*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, 'I', state.MAX_LEN);
611*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
612*8d67ca89SAndroid Build Coastguard Worker
613*8d67ca89SAndroid Build Coastguard Worker if (pos > state.MAX_LEN - 1) {
614*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
615*8d67ca89SAndroid Build Coastguard Worker state.ptr[2 * state.MAX_LEN - 1] = '\0';
616*8d67ca89SAndroid Build Coastguard Worker } else {
617*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
618*8d67ca89SAndroid Build Coastguard Worker }
619*8d67ca89SAndroid Build Coastguard Worker
620*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
621*8d67ca89SAndroid Build Coastguard Worker ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
622*8d67ca89SAndroid Build Coastguard Worker (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
623*8d67ca89SAndroid Build Coastguard Worker }
624*8d67ca89SAndroid Build Coastguard Worker #else
625*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "strlcpy not available";
626*8d67ca89SAndroid Build Coastguard Worker #endif
627*8d67ca89SAndroid Build Coastguard Worker }
628*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strncat)629*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strncat) {
630*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
631*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i < state.n; i++) {
632*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
633*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, '\2', state.MAX_LEN);
634*8d67ca89SAndroid Build Coastguard Worker state.ptr2[state.MAX_LEN - 1] = '\0';
635*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
636*8d67ca89SAndroid Build Coastguard Worker
637*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'I', state.len[i]);
638*8d67ca89SAndroid Build Coastguard Worker state.ptr1[random() % state.len[i]] = '\0';
639*8d67ca89SAndroid Build Coastguard Worker state.ptr1[state.len[i] - 1] = '\0';
640*8d67ca89SAndroid Build Coastguard Worker
641*8d67ca89SAndroid Build Coastguard Worker size_t pos = strlen(state.ptr1);
642*8d67ca89SAndroid Build Coastguard Worker
643*8d67ca89SAndroid Build Coastguard Worker size_t actual = random() % state.len[i];
644*8d67ca89SAndroid Build Coastguard Worker strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
645*8d67ca89SAndroid Build Coastguard Worker state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
646*8d67ca89SAndroid Build Coastguard Worker
647*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
648*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
649*8d67ca89SAndroid Build Coastguard Worker }
650*8d67ca89SAndroid Build Coastguard Worker }
651*8d67ca89SAndroid Build Coastguard Worker }
652*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strncmp)653*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strncmp) {
654*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
655*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i < state.n; i++) {
656*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
657*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'v', state.MAX_LEN);
658*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, 'n', state.MAX_LEN);
659*8d67ca89SAndroid Build Coastguard Worker state.ptr1[state.len[i] - 1] = '\0';
660*8d67ca89SAndroid Build Coastguard Worker state.ptr2[state.len[i] - 1] = '\0';
661*8d67ca89SAndroid Build Coastguard Worker
662*8d67ca89SAndroid Build Coastguard Worker size_t pos = 1 + (random() % (state.MAX_LEN - 1));
663*8d67ca89SAndroid Build Coastguard Worker int actual;
664*8d67ca89SAndroid Build Coastguard Worker int expected;
665*8d67ca89SAndroid Build Coastguard Worker if (pos >= state.len[i] - 1) {
666*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr1, state.ptr2, state.len[i]);
667*8d67ca89SAndroid Build Coastguard Worker expected = 0;
668*8d67ca89SAndroid Build Coastguard Worker actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
669*8d67ca89SAndroid Build Coastguard Worker } else {
670*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr1, state.ptr2, pos);
671*8d67ca89SAndroid Build Coastguard Worker if (state.ptr1[pos] > state.ptr2[pos]) {
672*8d67ca89SAndroid Build Coastguard Worker expected = 1;
673*8d67ca89SAndroid Build Coastguard Worker } else if (state.ptr1[pos] == state.ptr2[pos]) {
674*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos + 1] = '\0';
675*8d67ca89SAndroid Build Coastguard Worker state.ptr2[pos + 1] = '\0';
676*8d67ca89SAndroid Build Coastguard Worker expected = 0;
677*8d67ca89SAndroid Build Coastguard Worker } else {
678*8d67ca89SAndroid Build Coastguard Worker expected = -1;
679*8d67ca89SAndroid Build Coastguard Worker }
680*8d67ca89SAndroid Build Coastguard Worker actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
681*8d67ca89SAndroid Build Coastguard Worker }
682*8d67ca89SAndroid Build Coastguard Worker
683*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(expected, signum(actual));
684*8d67ca89SAndroid Build Coastguard Worker }
685*8d67ca89SAndroid Build Coastguard Worker }
686*8d67ca89SAndroid Build Coastguard Worker }
687*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,stpncpy)688*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, stpncpy) {
689*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
690*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
691*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'J', state.MAX_LEN);
692*8d67ca89SAndroid Build Coastguard Worker // Choose a random size for our src buffer.
693*8d67ca89SAndroid Build Coastguard Worker size_t ptr1_len = random() % state.MAX_LEN;
694*8d67ca89SAndroid Build Coastguard Worker state.ptr1[ptr1_len] = '\0';
695*8d67ca89SAndroid Build Coastguard Worker // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
696*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr1, state.MAX_LEN);
697*8d67ca89SAndroid Build Coastguard Worker // Init ptr2 to a set value.
698*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, '\1', state.MAX_LEN);
699*8d67ca89SAndroid Build Coastguard Worker
700*8d67ca89SAndroid Build Coastguard Worker // Choose a random amount of data to copy.
701*8d67ca89SAndroid Build Coastguard Worker size_t copy_len = random() % state.MAX_LEN;
702*8d67ca89SAndroid Build Coastguard Worker
703*8d67ca89SAndroid Build Coastguard Worker // Set the second half of ptr to the expected pattern in ptr2.
704*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
705*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
706*8d67ca89SAndroid Build Coastguard Worker size_t expected_end;
707*8d67ca89SAndroid Build Coastguard Worker if (copy_len > ptr1_len) {
708*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
709*8d67ca89SAndroid Build Coastguard Worker expected_end = ptr1_len;
710*8d67ca89SAndroid Build Coastguard Worker } else {
711*8d67ca89SAndroid Build Coastguard Worker expected_end = copy_len;
712*8d67ca89SAndroid Build Coastguard Worker }
713*8d67ca89SAndroid Build Coastguard Worker
714*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
715*8d67ca89SAndroid Build Coastguard Worker
716*8d67ca89SAndroid Build Coastguard Worker // Verify ptr1 was not modified.
717*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
718*8d67ca89SAndroid Build Coastguard Worker // Verify ptr2 contains the expected data.
719*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
720*8d67ca89SAndroid Build Coastguard Worker }
721*8d67ca89SAndroid Build Coastguard Worker }
722*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strncpy)723*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strncpy) {
724*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
725*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
726*8d67ca89SAndroid Build Coastguard Worker // Choose a random value to fill the string, except \0 (string terminator),
727*8d67ca89SAndroid Build Coastguard Worker // or \1 (guarantees it's different from anything in ptr2).
728*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'K', state.MAX_LEN);
729*8d67ca89SAndroid Build Coastguard Worker // Choose a random size for our src buffer.
730*8d67ca89SAndroid Build Coastguard Worker size_t ptr1_len = random() % state.MAX_LEN;
731*8d67ca89SAndroid Build Coastguard Worker state.ptr1[ptr1_len] = '\0';
732*8d67ca89SAndroid Build Coastguard Worker // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
733*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr1, state.MAX_LEN);
734*8d67ca89SAndroid Build Coastguard Worker // Init ptr2 to a set value.
735*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, '\1', state.MAX_LEN);
736*8d67ca89SAndroid Build Coastguard Worker
737*8d67ca89SAndroid Build Coastguard Worker // Choose a random amount of data to copy.
738*8d67ca89SAndroid Build Coastguard Worker size_t copy_len = random() % state.MAX_LEN;
739*8d67ca89SAndroid Build Coastguard Worker
740*8d67ca89SAndroid Build Coastguard Worker // Set the second half of ptr to the expected pattern in ptr2.
741*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
742*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
743*8d67ca89SAndroid Build Coastguard Worker if (copy_len > ptr1_len) {
744*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
745*8d67ca89SAndroid Build Coastguard Worker }
746*8d67ca89SAndroid Build Coastguard Worker
747*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(state.ptr2, strncpy(state.ptr2, state.ptr1, copy_len));
748*8d67ca89SAndroid Build Coastguard Worker
749*8d67ca89SAndroid Build Coastguard Worker // Verify ptr1 was not modified.
750*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
751*8d67ca89SAndroid Build Coastguard Worker // Verify ptr2 contains the expected data.
752*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
753*8d67ca89SAndroid Build Coastguard Worker }
754*8d67ca89SAndroid Build Coastguard Worker }
755*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strrchr)756*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strrchr) {
757*8d67ca89SAndroid Build Coastguard Worker int seek_char = 'M';
758*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
759*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i < state.n; i++) {
760*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
761*8d67ca89SAndroid Build Coastguard Worker if (~seek_char > 0) {
762*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, ~seek_char, state.len[i]);
763*8d67ca89SAndroid Build Coastguard Worker } else {
764*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, '\1', state.len[i]);
765*8d67ca89SAndroid Build Coastguard Worker }
766*8d67ca89SAndroid Build Coastguard Worker state.ptr1[state.len[i] - 1] = '\0';
767*8d67ca89SAndroid Build Coastguard Worker
768*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % state.MAX_LEN;
769*8d67ca89SAndroid Build Coastguard Worker char* expected;
770*8d67ca89SAndroid Build Coastguard Worker if (pos >= state.len[i] - 1) {
771*8d67ca89SAndroid Build Coastguard Worker if (seek_char == 0) {
772*8d67ca89SAndroid Build Coastguard Worker expected = state.ptr1 + state.len[i] - 1;
773*8d67ca89SAndroid Build Coastguard Worker } else {
774*8d67ca89SAndroid Build Coastguard Worker expected = nullptr;
775*8d67ca89SAndroid Build Coastguard Worker }
776*8d67ca89SAndroid Build Coastguard Worker } else {
777*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos] = seek_char;
778*8d67ca89SAndroid Build Coastguard Worker expected = state.ptr1 + pos;
779*8d67ca89SAndroid Build Coastguard Worker }
780*8d67ca89SAndroid Build Coastguard Worker
781*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
782*8d67ca89SAndroid Build Coastguard Worker }
783*8d67ca89SAndroid Build Coastguard Worker }
784*8d67ca89SAndroid Build Coastguard Worker }
785*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memchr)786*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memchr) {
787*8d67ca89SAndroid Build Coastguard Worker int seek_char = 'N';
788*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
789*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n; i++) {
790*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
791*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, ~seek_char, state.len[i]);
792*8d67ca89SAndroid Build Coastguard Worker
793*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % state.MAX_LEN;
794*8d67ca89SAndroid Build Coastguard Worker char* expected;
795*8d67ca89SAndroid Build Coastguard Worker if (pos >= state.len[i]) {
796*8d67ca89SAndroid Build Coastguard Worker expected = nullptr;
797*8d67ca89SAndroid Build Coastguard Worker } else {
798*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos] = seek_char;
799*8d67ca89SAndroid Build Coastguard Worker expected = state.ptr1 + pos;
800*8d67ca89SAndroid Build Coastguard Worker }
801*8d67ca89SAndroid Build Coastguard Worker
802*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
803*8d67ca89SAndroid Build Coastguard Worker }
804*8d67ca89SAndroid Build Coastguard Worker }
805*8d67ca89SAndroid Build Coastguard Worker }
806*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memchr_zero)807*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memchr_zero) {
808*8d67ca89SAndroid Build Coastguard Worker uint8_t* buffer;
809*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, posix_memalign(reinterpret_cast<void**>(&buffer), 64, 64));
810*8d67ca89SAndroid Build Coastguard Worker memset(buffer, 10, 64);
811*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(nullptr == memchr(buffer, 5, 0));
812*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(nullptr == memchr(buffer, 10, 0));
813*8d67ca89SAndroid Build Coastguard Worker }
814*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memrchr)815*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memrchr) {
816*8d67ca89SAndroid Build Coastguard Worker int seek_char = 'P';
817*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
818*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n; i++) {
819*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
820*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, ~seek_char, state.len[i]);
821*8d67ca89SAndroid Build Coastguard Worker
822*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % state.MAX_LEN;
823*8d67ca89SAndroid Build Coastguard Worker char* expected;
824*8d67ca89SAndroid Build Coastguard Worker if (pos >= state.len[i]) {
825*8d67ca89SAndroid Build Coastguard Worker expected = nullptr;
826*8d67ca89SAndroid Build Coastguard Worker } else {
827*8d67ca89SAndroid Build Coastguard Worker state.ptr1[pos] = seek_char;
828*8d67ca89SAndroid Build Coastguard Worker expected = state.ptr1 + pos;
829*8d67ca89SAndroid Build Coastguard Worker }
830*8d67ca89SAndroid Build Coastguard Worker
831*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
832*8d67ca89SAndroid Build Coastguard Worker }
833*8d67ca89SAndroid Build Coastguard Worker }
834*8d67ca89SAndroid Build Coastguard Worker }
835*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memcmp)836*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memcmp) {
837*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(SMALL);
838*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n; i++) {
839*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
840*8d67ca89SAndroid Build Coastguard Worker int c1 = 'A';
841*8d67ca89SAndroid Build Coastguard Worker int c2 = 'N';
842*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, c1, state.MAX_LEN);
843*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, c1, state.MAX_LEN);
844*8d67ca89SAndroid Build Coastguard Worker
845*8d67ca89SAndroid Build Coastguard Worker int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
846*8d67ca89SAndroid Build Coastguard Worker state.ptr2[pos] = c2;
847*8d67ca89SAndroid Build Coastguard Worker
848*8d67ca89SAndroid Build Coastguard Worker int expected = (static_cast<int>(c1) - static_cast<int>(c2));
849*8d67ca89SAndroid Build Coastguard Worker int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
850*8d67ca89SAndroid Build Coastguard Worker
851*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(signum(expected), signum(actual));
852*8d67ca89SAndroid Build Coastguard Worker }
853*8d67ca89SAndroid Build Coastguard Worker }
854*8d67ca89SAndroid Build Coastguard Worker }
855*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,wmemcmp)856*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, wmemcmp) {
857*8d67ca89SAndroid Build Coastguard Worker StringTestState<wchar_t> state(SMALL);
858*8d67ca89SAndroid Build Coastguard Worker
859*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n; i++) {
860*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
861*8d67ca89SAndroid Build Coastguard Worker long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1;
862*8d67ca89SAndroid Build Coastguard Worker int c1 = rand() & mask;
863*8d67ca89SAndroid Build Coastguard Worker int c2 = rand() & mask;
864*8d67ca89SAndroid Build Coastguard Worker wmemset(state.ptr1, c1, state.MAX_LEN);
865*8d67ca89SAndroid Build Coastguard Worker wmemset(state.ptr2, c1, state.MAX_LEN);
866*8d67ca89SAndroid Build Coastguard Worker
867*8d67ca89SAndroid Build Coastguard Worker int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
868*8d67ca89SAndroid Build Coastguard Worker state.ptr2[pos] = c2;
869*8d67ca89SAndroid Build Coastguard Worker
870*8d67ca89SAndroid Build Coastguard Worker int expected = (static_cast<int>(c1) - static_cast<int>(c2));
871*8d67ca89SAndroid Build Coastguard Worker int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
872*8d67ca89SAndroid Build Coastguard Worker
873*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(signum(expected), signum(actual));
874*8d67ca89SAndroid Build Coastguard Worker }
875*8d67ca89SAndroid Build Coastguard Worker }
876*8d67ca89SAndroid Build Coastguard Worker }
877*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memcpy)878*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memcpy) {
879*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(LARGE);
880*8d67ca89SAndroid Build Coastguard Worker int rand = 4;
881*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n - 1; i++) {
882*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
883*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % (state.MAX_LEN - state.len[i]);
884*8d67ca89SAndroid Build Coastguard Worker
885*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, rand, state.len[i]);
886*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
887*8d67ca89SAndroid Build Coastguard Worker
888*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2, rand, state.len[i]);
889*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
890*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2 + pos, '\0', state.len[i]);
891*8d67ca89SAndroid Build Coastguard Worker
892*8d67ca89SAndroid Build Coastguard Worker ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
893*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
894*8d67ca89SAndroid Build Coastguard Worker }
895*8d67ca89SAndroid Build Coastguard Worker }
896*8d67ca89SAndroid Build Coastguard Worker }
897*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memset)898*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memset) {
899*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(LARGE);
900*8d67ca89SAndroid Build Coastguard Worker char ch = 'P';
901*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n - 1; i++) {
902*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
903*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, ~ch, state.MAX_LEN);
904*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
905*8d67ca89SAndroid Build Coastguard Worker
906*8d67ca89SAndroid Build Coastguard Worker size_t pos = random () % (state.MAX_LEN - state.len[i]);
907*8d67ca89SAndroid Build Coastguard Worker for (size_t k = pos; k < pos + state.len[i]; k++) {
908*8d67ca89SAndroid Build Coastguard Worker state.ptr1[k] = ch;
909*8d67ca89SAndroid Build Coastguard Worker }
910*8d67ca89SAndroid Build Coastguard Worker
911*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
912*8d67ca89SAndroid Build Coastguard Worker
913*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
914*8d67ca89SAndroid Build Coastguard Worker }
915*8d67ca89SAndroid Build Coastguard Worker }
916*8d67ca89SAndroid Build Coastguard Worker }
917*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memmove)918*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memmove) {
919*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(LARGE);
920*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n - 1; i++) {
921*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
922*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'Q', 2 * state.MAX_LEN);
923*8d67ca89SAndroid Build Coastguard Worker
924*8d67ca89SAndroid Build Coastguard Worker size_t pos = random() % (state.MAX_LEN - state.len[i]);
925*8d67ca89SAndroid Build Coastguard Worker
926*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'R', state.len[i]);
927*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
928*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr, state.ptr1, state.len[i]);
929*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
930*8d67ca89SAndroid Build Coastguard Worker
931*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
932*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
933*8d67ca89SAndroid Build Coastguard Worker }
934*8d67ca89SAndroid Build Coastguard Worker }
935*8d67ca89SAndroid Build Coastguard Worker }
936*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memmove_cache_size)937*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memmove_cache_size) {
938*8d67ca89SAndroid Build Coastguard Worker size_t len = 600000;
939*8d67ca89SAndroid Build Coastguard Worker int max_alignment = 31;
940*8d67ca89SAndroid Build Coastguard Worker int alignments[] = {0, 5, 11, 29, 30};
941*8d67ca89SAndroid Build Coastguard Worker char* ptr = reinterpret_cast<char*>(malloc(sizeof(char) * len));
942*8d67ca89SAndroid Build Coastguard Worker char* ptr1 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len));
943*8d67ca89SAndroid Build Coastguard Worker char* glob_ptr2 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len + max_alignment));
944*8d67ca89SAndroid Build Coastguard Worker size_t pos = 64;
945*8d67ca89SAndroid Build Coastguard Worker
946*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
947*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr1 != nullptr);
948*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(glob_ptr2 != nullptr);
949*8d67ca89SAndroid Build Coastguard Worker
950*8d67ca89SAndroid Build Coastguard Worker for (int i = 0; i < 5; i++) {
951*8d67ca89SAndroid Build Coastguard Worker char* ptr2 = glob_ptr2 + alignments[i];
952*8d67ca89SAndroid Build Coastguard Worker memset(ptr1, 'S', 2 * len);
953*8d67ca89SAndroid Build Coastguard Worker memset(ptr1, 'T', len);
954*8d67ca89SAndroid Build Coastguard Worker memcpy(ptr2, ptr1, 2 * len);
955*8d67ca89SAndroid Build Coastguard Worker memcpy(ptr, ptr1, len);
956*8d67ca89SAndroid Build Coastguard Worker memcpy(ptr1 + pos, ptr, len);
957*8d67ca89SAndroid Build Coastguard Worker
958*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memmove(ptr2 + pos, ptr, len) == ptr2 + pos);
959*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(ptr2, ptr1, 2 * len));
960*8d67ca89SAndroid Build Coastguard Worker }
961*8d67ca89SAndroid Build Coastguard Worker free(ptr);
962*8d67ca89SAndroid Build Coastguard Worker free(ptr1);
963*8d67ca89SAndroid Build Coastguard Worker free(glob_ptr2);
964*8d67ca89SAndroid Build Coastguard Worker }
965*8d67ca89SAndroid Build Coastguard Worker
verify_memmove(char * src_copy,char * dst,char * src,size_t size)966*8d67ca89SAndroid Build Coastguard Worker static void verify_memmove(char* src_copy, char* dst, char* src, size_t size) {
967*8d67ca89SAndroid Build Coastguard Worker memset(dst, 0, size);
968*8d67ca89SAndroid Build Coastguard Worker memcpy(src, src_copy, size);
969*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(dst, memmove(dst, src, size));
970*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(dst, src_copy, size));
971*8d67ca89SAndroid Build Coastguard Worker }
972*8d67ca89SAndroid Build Coastguard Worker
973*8d67ca89SAndroid Build Coastguard Worker #define MEMMOVE_DATA_SIZE (1024*1024*3)
974*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memmove_check)975*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memmove_check) {
976*8d67ca89SAndroid Build Coastguard Worker char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
977*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(buffer != nullptr);
978*8d67ca89SAndroid Build Coastguard Worker
979*8d67ca89SAndroid Build Coastguard Worker char* src_data = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
980*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(src_data != nullptr);
981*8d67ca89SAndroid Build Coastguard Worker // Initialize to a known pattern to copy into src for each test and
982*8d67ca89SAndroid Build Coastguard Worker // to compare dst against.
983*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < MEMMOVE_DATA_SIZE; i++) {
984*8d67ca89SAndroid Build Coastguard Worker src_data[i] = (i + 1) % 255;
985*8d67ca89SAndroid Build Coastguard Worker }
986*8d67ca89SAndroid Build Coastguard Worker
987*8d67ca89SAndroid Build Coastguard Worker // Check all different dst offsets between 0 and 127 inclusive.
988*8d67ca89SAndroid Build Coastguard Worker char* src = buffer;
989*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 127; i++) {
990*8d67ca89SAndroid Build Coastguard Worker char* dst = buffer + 256 + i;
991*8d67ca89SAndroid Build Coastguard Worker // Small copy.
992*8d67ca89SAndroid Build Coastguard Worker verify_memmove(src_data, dst, src, 1024);
993*8d67ca89SAndroid Build Coastguard Worker
994*8d67ca89SAndroid Build Coastguard Worker // Medium copy.
995*8d67ca89SAndroid Build Coastguard Worker verify_memmove(src_data, dst, src, 64 * 1024);
996*8d67ca89SAndroid Build Coastguard Worker
997*8d67ca89SAndroid Build Coastguard Worker // Medium copy.
998*8d67ca89SAndroid Build Coastguard Worker verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
999*8d67ca89SAndroid Build Coastguard Worker }
1000*8d67ca89SAndroid Build Coastguard Worker
1001*8d67ca89SAndroid Build Coastguard Worker // Check all leftover size offsets between 1 and 127 inclusive.
1002*8d67ca89SAndroid Build Coastguard Worker char* dst = buffer + 256;
1003*8d67ca89SAndroid Build Coastguard Worker src = buffer;
1004*8d67ca89SAndroid Build Coastguard Worker for (size_t size = 1; size < 127; size++) {
1005*8d67ca89SAndroid Build Coastguard Worker // Small copy.
1006*8d67ca89SAndroid Build Coastguard Worker verify_memmove(src_data, dst, src, 1024);
1007*8d67ca89SAndroid Build Coastguard Worker
1008*8d67ca89SAndroid Build Coastguard Worker // Medium copy.
1009*8d67ca89SAndroid Build Coastguard Worker verify_memmove(src_data, dst, src, 64 * 1024);
1010*8d67ca89SAndroid Build Coastguard Worker
1011*8d67ca89SAndroid Build Coastguard Worker // Large copy.
1012*8d67ca89SAndroid Build Coastguard Worker verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
1013*8d67ca89SAndroid Build Coastguard Worker }
1014*8d67ca89SAndroid Build Coastguard Worker }
1015*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,bcopy)1016*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, bcopy) {
1017*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(LARGE);
1018*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < state.n; i++) {
1019*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
1020*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, '4', state.MAX_LEN);
1021*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1 + state.MAX_LEN, 'a', state.MAX_LEN);
1022*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
1023*8d67ca89SAndroid Build Coastguard Worker
1024*8d67ca89SAndroid Build Coastguard Worker size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
1025*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
1026*8d67ca89SAndroid Build Coastguard Worker
1027*8d67ca89SAndroid Build Coastguard Worker bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
1028*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
1029*8d67ca89SAndroid Build Coastguard Worker }
1030*8d67ca89SAndroid Build Coastguard Worker }
1031*8d67ca89SAndroid Build Coastguard Worker }
1032*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,bzero)1033*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, bzero) {
1034*8d67ca89SAndroid Build Coastguard Worker StringTestState<char> state(LARGE);
1035*8d67ca89SAndroid Build Coastguard Worker for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
1036*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr1, 'R', state.MAX_LEN);
1037*8d67ca89SAndroid Build Coastguard Worker
1038*8d67ca89SAndroid Build Coastguard Worker size_t start = random() % state.MAX_LEN;
1039*8d67ca89SAndroid Build Coastguard Worker size_t end = start + random() % (state.MAX_LEN - start);
1040*8d67ca89SAndroid Build Coastguard Worker
1041*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr2, state.ptr1, start);
1042*8d67ca89SAndroid Build Coastguard Worker memset(state.ptr2 + start, '\0', end - start);
1043*8d67ca89SAndroid Build Coastguard Worker memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
1044*8d67ca89SAndroid Build Coastguard Worker
1045*8d67ca89SAndroid Build Coastguard Worker bzero(state.ptr1 + start, end - start);
1046*8d67ca89SAndroid Build Coastguard Worker
1047*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
1048*8d67ca89SAndroid Build Coastguard Worker }
1049*8d67ca89SAndroid Build Coastguard Worker }
1050*8d67ca89SAndroid Build Coastguard Worker
DoMemcpyTest(uint8_t * src,uint8_t * dst,size_t len)1051*8d67ca89SAndroid Build Coastguard Worker static void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1052*8d67ca89SAndroid Build Coastguard Worker memset(src, (len % 255) + 1, len);
1053*8d67ca89SAndroid Build Coastguard Worker memset(dst, 0, len);
1054*8d67ca89SAndroid Build Coastguard Worker
1055*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(dst, memcpy(dst, src, len));
1056*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst, len) == 0);
1057*8d67ca89SAndroid Build Coastguard Worker }
1058*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memcpy_align)1059*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memcpy_align) {
1060*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
1061*8d67ca89SAndroid Build Coastguard Worker }
1062*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memcpy_overread)1063*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memcpy_overread) {
1064*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferOverreadTest(DoMemcpyTest);
1065*8d67ca89SAndroid Build Coastguard Worker }
1066*8d67ca89SAndroid Build Coastguard Worker
DoMemmoveTest(uint8_t * src,uint8_t * dst,size_t len)1067*8d67ca89SAndroid Build Coastguard Worker static void DoMemmoveTest(uint8_t* src, uint8_t* dst, size_t len) {
1068*8d67ca89SAndroid Build Coastguard Worker memset(src, (len % 255) + 1, len);
1069*8d67ca89SAndroid Build Coastguard Worker memset(dst, 0, len);
1070*8d67ca89SAndroid Build Coastguard Worker
1071*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(dst, memmove(dst, src, len));
1072*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst, len) == 0);
1073*8d67ca89SAndroid Build Coastguard Worker }
1074*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memmove_align)1075*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memmove_align) {
1076*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
1077*8d67ca89SAndroid Build Coastguard Worker }
1078*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memmove_overread)1079*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memmove_overread) {
1080*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferOverreadTest(DoMemmoveTest);
1081*8d67ca89SAndroid Build Coastguard Worker }
1082*8d67ca89SAndroid Build Coastguard Worker
DoMemsetTest(uint8_t * buf,size_t len)1083*8d67ca89SAndroid Build Coastguard Worker static void DoMemsetTest(uint8_t* buf, size_t len) {
1084*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < len; i++) {
1085*8d67ca89SAndroid Build Coastguard Worker buf[i] = 0;
1086*8d67ca89SAndroid Build Coastguard Worker }
1087*8d67ca89SAndroid Build Coastguard Worker int value = (len % 255) + 1;
1088*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buf, memset(buf, value, len));
1089*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < len; i++) {
1090*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(value, buf[i]);
1091*8d67ca89SAndroid Build Coastguard Worker }
1092*8d67ca89SAndroid Build Coastguard Worker }
1093*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memset_align)1094*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memset_align) {
1095*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferAlignTest(LARGE, DoMemsetTest);
1096*8d67ca89SAndroid Build Coastguard Worker }
1097*8d67ca89SAndroid Build Coastguard Worker
DoStrlenTest(uint8_t * buf,size_t len)1098*8d67ca89SAndroid Build Coastguard Worker static void DoStrlenTest(uint8_t* buf, size_t len) {
1099*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1100*8d67ca89SAndroid Build Coastguard Worker memset(buf, (32 + (len % 96)), len - 1);
1101*8d67ca89SAndroid Build Coastguard Worker buf[len-1] = '\0';
1102*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf)));
1103*8d67ca89SAndroid Build Coastguard Worker }
1104*8d67ca89SAndroid Build Coastguard Worker }
1105*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strlen_align)1106*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strlen_align) {
1107*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferAlignTest(LARGE, DoStrlenTest);
1108*8d67ca89SAndroid Build Coastguard Worker }
1109*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strlen_overread)1110*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strlen_overread) {
1111*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferOverreadTest(DoStrlenTest);
1112*8d67ca89SAndroid Build Coastguard Worker }
1113*8d67ca89SAndroid Build Coastguard Worker
DoStrcpyTest(uint8_t * src,uint8_t * dst,size_t len)1114*8d67ca89SAndroid Build Coastguard Worker static void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1115*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1116*8d67ca89SAndroid Build Coastguard Worker memset(src, (32 + (len % 96)), len - 1);
1117*8d67ca89SAndroid Build Coastguard Worker src[len-1] = '\0';
1118*8d67ca89SAndroid Build Coastguard Worker memset(dst, 0, len);
1119*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst),
1120*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(src))));
1121*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst, len) == 0);
1122*8d67ca89SAndroid Build Coastguard Worker }
1123*8d67ca89SAndroid Build Coastguard Worker }
1124*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcpy_align)1125*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcpy_align) {
1126*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
1127*8d67ca89SAndroid Build Coastguard Worker }
1128*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcpy_overread)1129*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcpy_overread) {
1130*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferOverreadTest(DoStrcpyTest);
1131*8d67ca89SAndroid Build Coastguard Worker }
1132*8d67ca89SAndroid Build Coastguard Worker
1133*8d67ca89SAndroid Build Coastguard Worker #if defined(STRLCPY_SUPPORTED)
DoStrlcpyTest(uint8_t * src,uint8_t * dst,size_t len)1134*8d67ca89SAndroid Build Coastguard Worker static void DoStrlcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1135*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1136*8d67ca89SAndroid Build Coastguard Worker memset(src, (32 + (len % 96)), len - 1);
1137*8d67ca89SAndroid Build Coastguard Worker src[len-1] = '\0';
1138*8d67ca89SAndroid Build Coastguard Worker memset(dst, 0, len);
1139*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(len-1, strlcpy(reinterpret_cast<char*>(dst),
1140*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(src), len));
1141*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst, len) == 0);
1142*8d67ca89SAndroid Build Coastguard Worker }
1143*8d67ca89SAndroid Build Coastguard Worker }
1144*8d67ca89SAndroid Build Coastguard Worker #endif
1145*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strlcpy_align)1146*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strlcpy_align) {
1147*8d67ca89SAndroid Build Coastguard Worker #if defined(STRLCPY_SUPPORTED)
1148*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferAlignTest(LARGE, DoStrlcpyTest);
1149*8d67ca89SAndroid Build Coastguard Worker #else
1150*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "strlcpy not available";
1151*8d67ca89SAndroid Build Coastguard Worker #endif
1152*8d67ca89SAndroid Build Coastguard Worker }
1153*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strlcpy_overread)1154*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strlcpy_overread) {
1155*8d67ca89SAndroid Build Coastguard Worker #if defined(STRLCPY_SUPPORTED)
1156*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferOverreadTest(DoStrlcpyTest);
1157*8d67ca89SAndroid Build Coastguard Worker #else
1158*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "strlcpy not available";
1159*8d67ca89SAndroid Build Coastguard Worker #endif
1160*8d67ca89SAndroid Build Coastguard Worker }
1161*8d67ca89SAndroid Build Coastguard Worker
1162*8d67ca89SAndroid Build Coastguard Worker
DoStpcpyTest(uint8_t * src,uint8_t * dst,size_t len)1163*8d67ca89SAndroid Build Coastguard Worker static void DoStpcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1164*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1165*8d67ca89SAndroid Build Coastguard Worker memset(src, (32 + (len % 96)), len - 1);
1166*8d67ca89SAndroid Build Coastguard Worker src[len-1] = '\0';
1167*8d67ca89SAndroid Build Coastguard Worker memset(dst, 0, len);
1168*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(dst+len-1, reinterpret_cast<uint8_t*>(stpcpy(reinterpret_cast<char*>(dst),
1169*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(src))));
1170*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst, len) == 0);
1171*8d67ca89SAndroid Build Coastguard Worker }
1172*8d67ca89SAndroid Build Coastguard Worker }
1173*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,stpcpy_align)1174*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, stpcpy_align) {
1175*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest);
1176*8d67ca89SAndroid Build Coastguard Worker }
1177*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,stpcpy_overread)1178*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, stpcpy_overread) {
1179*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferOverreadTest(DoStpcpyTest);
1180*8d67ca89SAndroid Build Coastguard Worker }
1181*8d67ca89SAndroid Build Coastguard Worker
1182*8d67ca89SAndroid Build Coastguard Worker // Use our own incrementer to cut down on the total number of calls.
LargeSetIncrement(size_t len)1183*8d67ca89SAndroid Build Coastguard Worker static size_t LargeSetIncrement(size_t len) {
1184*8d67ca89SAndroid Build Coastguard Worker if (len >= 4096) {
1185*8d67ca89SAndroid Build Coastguard Worker return 4096;
1186*8d67ca89SAndroid Build Coastguard Worker } else if (len >= 1024) {
1187*8d67ca89SAndroid Build Coastguard Worker return 1024;
1188*8d67ca89SAndroid Build Coastguard Worker } else if (len >= 256) {
1189*8d67ca89SAndroid Build Coastguard Worker return 256;
1190*8d67ca89SAndroid Build Coastguard Worker }
1191*8d67ca89SAndroid Build Coastguard Worker return 1;
1192*8d67ca89SAndroid Build Coastguard Worker }
1193*8d67ca89SAndroid Build Coastguard Worker
1194*8d67ca89SAndroid Build Coastguard Worker #define STRCAT_DST_LEN 64
1195*8d67ca89SAndroid Build Coastguard Worker
DoStrcatTest(uint8_t * src,uint8_t * dst,size_t len)1196*8d67ca89SAndroid Build Coastguard Worker static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) {
1197*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1198*8d67ca89SAndroid Build Coastguard Worker int value = 32 + (len % 96);
1199*8d67ca89SAndroid Build Coastguard Worker memset(src, value, len - 1);
1200*8d67ca89SAndroid Build Coastguard Worker src[len-1] = '\0';
1201*8d67ca89SAndroid Build Coastguard Worker
1202*8d67ca89SAndroid Build Coastguard Worker if (len >= STRCAT_DST_LEN) {
1203*8d67ca89SAndroid Build Coastguard Worker // Create a small buffer for doing quick compares in each loop.
1204*8d67ca89SAndroid Build Coastguard Worker uint8_t cmp_buf[STRCAT_DST_LEN];
1205*8d67ca89SAndroid Build Coastguard Worker // Make sure dst string contains a different value then the src string.
1206*8d67ca89SAndroid Build Coastguard Worker int value2 = 32 + (value + 2) % 96;
1207*8d67ca89SAndroid Build Coastguard Worker memset(cmp_buf, value2, sizeof(cmp_buf));
1208*8d67ca89SAndroid Build Coastguard Worker
1209*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i <= STRCAT_DST_LEN;) {
1210*8d67ca89SAndroid Build Coastguard Worker memset(dst, value2, i-1);
1211*8d67ca89SAndroid Build Coastguard Worker memset(dst+i-1, 0, len-i);
1212*8d67ca89SAndroid Build Coastguard Worker src[len-i] = '\0';
1213*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
1214*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(src))));
1215*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
1216*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
1217*8d67ca89SAndroid Build Coastguard Worker // This is an expensive loop, so don't loop through every value,
1218*8d67ca89SAndroid Build Coastguard Worker // get to a certain size and then start doubling.
1219*8d67ca89SAndroid Build Coastguard Worker if (i < 16) {
1220*8d67ca89SAndroid Build Coastguard Worker i++;
1221*8d67ca89SAndroid Build Coastguard Worker } else {
1222*8d67ca89SAndroid Build Coastguard Worker i <<= 1;
1223*8d67ca89SAndroid Build Coastguard Worker }
1224*8d67ca89SAndroid Build Coastguard Worker }
1225*8d67ca89SAndroid Build Coastguard Worker } else {
1226*8d67ca89SAndroid Build Coastguard Worker dst[0] = '\0';
1227*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
1228*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(src))));
1229*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst, len) == 0);
1230*8d67ca89SAndroid Build Coastguard Worker }
1231*8d67ca89SAndroid Build Coastguard Worker }
1232*8d67ca89SAndroid Build Coastguard Worker }
1233*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcat_align)1234*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcat_align) {
1235*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement);
1236*8d67ca89SAndroid Build Coastguard Worker }
1237*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcat_overread)1238*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcat_overread) {
1239*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferOverreadTest(DoStrcatTest);
1240*8d67ca89SAndroid Build Coastguard Worker }
1241*8d67ca89SAndroid Build Coastguard Worker
1242*8d67ca89SAndroid Build Coastguard Worker #if defined(STRLCAT_SUPPORTED)
DoStrlcatTest(uint8_t * src,uint8_t * dst,size_t len)1243*8d67ca89SAndroid Build Coastguard Worker static void DoStrlcatTest(uint8_t* src, uint8_t* dst, size_t len) {
1244*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1245*8d67ca89SAndroid Build Coastguard Worker int value = 32 + (len % 96);
1246*8d67ca89SAndroid Build Coastguard Worker memset(src, value, len - 1);
1247*8d67ca89SAndroid Build Coastguard Worker src[len-1] = '\0';
1248*8d67ca89SAndroid Build Coastguard Worker
1249*8d67ca89SAndroid Build Coastguard Worker if (len >= STRCAT_DST_LEN) {
1250*8d67ca89SAndroid Build Coastguard Worker // Create a small buffer for doing quick compares in each loop.
1251*8d67ca89SAndroid Build Coastguard Worker uint8_t cmp_buf[STRCAT_DST_LEN];
1252*8d67ca89SAndroid Build Coastguard Worker // Make sure dst string contains a different value then the src string.
1253*8d67ca89SAndroid Build Coastguard Worker int value2 = 32 + (value + 2) % 96;
1254*8d67ca89SAndroid Build Coastguard Worker memset(cmp_buf, value2, sizeof(cmp_buf));
1255*8d67ca89SAndroid Build Coastguard Worker
1256*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i <= STRCAT_DST_LEN;) {
1257*8d67ca89SAndroid Build Coastguard Worker memset(dst, value2, i-1);
1258*8d67ca89SAndroid Build Coastguard Worker memset(dst+i-1, 0, len-i);
1259*8d67ca89SAndroid Build Coastguard Worker src[len-i] = '\0';
1260*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(len-1, strlcat(reinterpret_cast<char*>(dst),
1261*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(src), len));
1262*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
1263*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
1264*8d67ca89SAndroid Build Coastguard Worker // This is an expensive loop, so don't loop through every value,
1265*8d67ca89SAndroid Build Coastguard Worker // get to a certain size and then start doubling.
1266*8d67ca89SAndroid Build Coastguard Worker if (i < 16) {
1267*8d67ca89SAndroid Build Coastguard Worker i++;
1268*8d67ca89SAndroid Build Coastguard Worker } else {
1269*8d67ca89SAndroid Build Coastguard Worker i <<= 1;
1270*8d67ca89SAndroid Build Coastguard Worker }
1271*8d67ca89SAndroid Build Coastguard Worker }
1272*8d67ca89SAndroid Build Coastguard Worker } else {
1273*8d67ca89SAndroid Build Coastguard Worker dst[0] = '\0';
1274*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(len-1, strlcat(reinterpret_cast<char*>(dst),
1275*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(src), len));
1276*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(src, dst, len) == 0);
1277*8d67ca89SAndroid Build Coastguard Worker }
1278*8d67ca89SAndroid Build Coastguard Worker }
1279*8d67ca89SAndroid Build Coastguard Worker }
1280*8d67ca89SAndroid Build Coastguard Worker #endif
1281*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strlcat_align)1282*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strlcat_align) {
1283*8d67ca89SAndroid Build Coastguard Worker #if defined(STRLCAT_SUPPORTED)
1284*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferAlignTest(MEDIUM, DoStrlcatTest, LargeSetIncrement);
1285*8d67ca89SAndroid Build Coastguard Worker #else
1286*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "strlcat not available";
1287*8d67ca89SAndroid Build Coastguard Worker #endif
1288*8d67ca89SAndroid Build Coastguard Worker }
1289*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strlcat_overread)1290*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strlcat_overread) {
1291*8d67ca89SAndroid Build Coastguard Worker #if defined(STRLCAT_SUPPORTED)
1292*8d67ca89SAndroid Build Coastguard Worker RunSrcDstBufferOverreadTest(DoStrlcatTest);
1293*8d67ca89SAndroid Build Coastguard Worker #else
1294*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "strlcat not available";
1295*8d67ca89SAndroid Build Coastguard Worker #endif
1296*8d67ca89SAndroid Build Coastguard Worker }
1297*8d67ca89SAndroid Build Coastguard Worker
DoStrcmpTest(uint8_t * buf1,uint8_t * buf2,size_t len)1298*8d67ca89SAndroid Build Coastguard Worker static void DoStrcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
1299*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1300*8d67ca89SAndroid Build Coastguard Worker memset(buf1, (32 + (len % 96)), len - 1);
1301*8d67ca89SAndroid Build Coastguard Worker buf1[len-1] = '\0';
1302*8d67ca89SAndroid Build Coastguard Worker memset(buf2, (32 + (len % 96)), len - 1);
1303*8d67ca89SAndroid Build Coastguard Worker buf2[len-1] = '\0';
1304*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, strcmp(reinterpret_cast<char*>(buf1),
1305*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(buf2)));
1306*8d67ca89SAndroid Build Coastguard Worker }
1307*8d67ca89SAndroid Build Coastguard Worker }
1308*8d67ca89SAndroid Build Coastguard Worker
DoStrcmpFailTest(uint8_t * buf1,uint8_t * buf2,size_t len1,size_t len2)1309*8d67ca89SAndroid Build Coastguard Worker static void DoStrcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
1310*8d67ca89SAndroid Build Coastguard Worker // Do string length differences.
1311*8d67ca89SAndroid Build Coastguard Worker int c = (32 + (len1 % 96));
1312*8d67ca89SAndroid Build Coastguard Worker memset(buf1, c, len1 - 1);
1313*8d67ca89SAndroid Build Coastguard Worker buf1[len1-1] = '\0';
1314*8d67ca89SAndroid Build Coastguard Worker memset(buf2, c, len2 - 1);
1315*8d67ca89SAndroid Build Coastguard Worker buf2[len2-1] = '\0';
1316*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1317*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(buf2)));
1318*8d67ca89SAndroid Build Coastguard Worker
1319*8d67ca89SAndroid Build Coastguard Worker // Do single character differences.
1320*8d67ca89SAndroid Build Coastguard Worker size_t len;
1321*8d67ca89SAndroid Build Coastguard Worker if (len1 > len2) {
1322*8d67ca89SAndroid Build Coastguard Worker len = len2;
1323*8d67ca89SAndroid Build Coastguard Worker } else {
1324*8d67ca89SAndroid Build Coastguard Worker len = len1;
1325*8d67ca89SAndroid Build Coastguard Worker }
1326*8d67ca89SAndroid Build Coastguard Worker // Need at least a two character buffer to do this test.
1327*8d67ca89SAndroid Build Coastguard Worker if (len > 1) {
1328*8d67ca89SAndroid Build Coastguard Worker buf1[len-1] = '\0';
1329*8d67ca89SAndroid Build Coastguard Worker buf2[len-1] = '\0';
1330*8d67ca89SAndroid Build Coastguard Worker int diff_c = (c + 1) % 96;
1331*8d67ca89SAndroid Build Coastguard Worker
1332*8d67ca89SAndroid Build Coastguard Worker buf1[len-2] = diff_c;
1333*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1334*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(buf2)));
1335*8d67ca89SAndroid Build Coastguard Worker
1336*8d67ca89SAndroid Build Coastguard Worker buf1[len-2] = c;
1337*8d67ca89SAndroid Build Coastguard Worker buf2[len-2] = diff_c;
1338*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1339*8d67ca89SAndroid Build Coastguard Worker reinterpret_cast<char*>(buf2)));
1340*8d67ca89SAndroid Build Coastguard Worker }
1341*8d67ca89SAndroid Build Coastguard Worker }
1342*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcmp_align)1343*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcmp_align) {
1344*8d67ca89SAndroid Build Coastguard Worker RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement);
1345*8d67ca89SAndroid Build Coastguard Worker }
1346*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcmp_overread)1347*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcmp_overread) {
1348*8d67ca89SAndroid Build Coastguard Worker RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest);
1349*8d67ca89SAndroid Build Coastguard Worker }
1350*8d67ca89SAndroid Build Coastguard Worker
DoMemcmpTest(uint8_t * buf1,uint8_t * buf2,size_t len)1351*8d67ca89SAndroid Build Coastguard Worker static void DoMemcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
1352*8d67ca89SAndroid Build Coastguard Worker memset(buf1, len+1, len);
1353*8d67ca89SAndroid Build Coastguard Worker memset(buf2, len+1, len);
1354*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf1, buf2, len));
1355*8d67ca89SAndroid Build Coastguard Worker }
1356*8d67ca89SAndroid Build Coastguard Worker
DoMemcmpFailTest(uint8_t * buf1,uint8_t * buf2,size_t len1,size_t len2)1357*8d67ca89SAndroid Build Coastguard Worker static void DoMemcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
1358*8d67ca89SAndroid Build Coastguard Worker size_t len;
1359*8d67ca89SAndroid Build Coastguard Worker if (len1 > len2) {
1360*8d67ca89SAndroid Build Coastguard Worker len = len2;
1361*8d67ca89SAndroid Build Coastguard Worker } else {
1362*8d67ca89SAndroid Build Coastguard Worker len = len1;
1363*8d67ca89SAndroid Build Coastguard Worker }
1364*8d67ca89SAndroid Build Coastguard Worker
1365*8d67ca89SAndroid Build Coastguard Worker memset(buf1, len2+1, len);
1366*8d67ca89SAndroid Build Coastguard Worker buf1[len-1] = len2;
1367*8d67ca89SAndroid Build Coastguard Worker memset(buf2, len2+1, len);
1368*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(0, memcmp(buf1, buf2, len));
1369*8d67ca89SAndroid Build Coastguard Worker
1370*8d67ca89SAndroid Build Coastguard Worker buf1[len-1] = len2+1;
1371*8d67ca89SAndroid Build Coastguard Worker buf2[len-1] = len2;
1372*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(0, memcmp(buf1, buf2, len));
1373*8d67ca89SAndroid Build Coastguard Worker }
1374*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memcmp_align)1375*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memcmp_align) {
1376*8d67ca89SAndroid Build Coastguard Worker RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement);
1377*8d67ca89SAndroid Build Coastguard Worker }
1378*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memcmp_overread)1379*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memcmp_overread) {
1380*8d67ca89SAndroid Build Coastguard Worker RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
1381*8d67ca89SAndroid Build Coastguard Worker }
1382*8d67ca89SAndroid Build Coastguard Worker
DoMemchrTest(uint8_t * buf,size_t len)1383*8d67ca89SAndroid Build Coastguard Worker static void DoMemchrTest(uint8_t* buf, size_t len) {
1384*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1385*8d67ca89SAndroid Build Coastguard Worker int value = len % 128;
1386*8d67ca89SAndroid Build Coastguard Worker int search_value = (len % 128) + 1;
1387*8d67ca89SAndroid Build Coastguard Worker memset(buf, value, len);
1388*8d67ca89SAndroid Build Coastguard Worker // The buffer does not contain the search value.
1389*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, memchr(buf, search_value, len));
1390*8d67ca89SAndroid Build Coastguard Worker if (len >= 2) {
1391*8d67ca89SAndroid Build Coastguard Worker buf[0] = search_value;
1392*8d67ca89SAndroid Build Coastguard Worker // The search value is the first element in the buffer.
1393*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(&buf[0], memchr(buf, search_value, len));
1394*8d67ca89SAndroid Build Coastguard Worker
1395*8d67ca89SAndroid Build Coastguard Worker buf[0] = value;
1396*8d67ca89SAndroid Build Coastguard Worker buf[len - 1] = search_value;
1397*8d67ca89SAndroid Build Coastguard Worker // The search value is the last element in the buffer.
1398*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(&buf[len - 1], memchr(buf, search_value, len));
1399*8d67ca89SAndroid Build Coastguard Worker }
1400*8d67ca89SAndroid Build Coastguard Worker }
1401*8d67ca89SAndroid Build Coastguard Worker }
1402*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memchr_align)1403*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memchr_align) {
1404*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferAlignTest(MEDIUM, DoMemchrTest);
1405*8d67ca89SAndroid Build Coastguard Worker }
1406*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memchr_overread)1407*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memchr_overread) {
1408*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferOverreadTest(DoMemchrTest);
1409*8d67ca89SAndroid Build Coastguard Worker }
1410*8d67ca89SAndroid Build Coastguard Worker
DoStrchrTest(uint8_t * buf,size_t len)1411*8d67ca89SAndroid Build Coastguard Worker static void DoStrchrTest(uint8_t* buf, size_t len) {
1412*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1413*8d67ca89SAndroid Build Coastguard Worker char value = 32 + (len % 96);
1414*8d67ca89SAndroid Build Coastguard Worker char search_value = 33 + (len % 96);
1415*8d67ca89SAndroid Build Coastguard Worker memset(buf, value, len - 1);
1416*8d67ca89SAndroid Build Coastguard Worker buf[len - 1] = '\0';
1417*8d67ca89SAndroid Build Coastguard Worker // The buffer does not contain the search value.
1418*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, strchr(reinterpret_cast<char*>(buf), search_value));
1419*8d67ca89SAndroid Build Coastguard Worker // Search for the special '\0' character.
1420*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 1]), strchr(reinterpret_cast<char*>(buf), '\0'));
1421*8d67ca89SAndroid Build Coastguard Worker if (len >= 2) {
1422*8d67ca89SAndroid Build Coastguard Worker buf[0] = search_value;
1423*8d67ca89SAndroid Build Coastguard Worker // The search value is the first element in the buffer.
1424*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strchr(reinterpret_cast<char*>(buf),
1425*8d67ca89SAndroid Build Coastguard Worker search_value));
1426*8d67ca89SAndroid Build Coastguard Worker
1427*8d67ca89SAndroid Build Coastguard Worker buf[0] = value;
1428*8d67ca89SAndroid Build Coastguard Worker buf[len - 2] = search_value;
1429*8d67ca89SAndroid Build Coastguard Worker // The search value is the second to last element in the buffer.
1430*8d67ca89SAndroid Build Coastguard Worker // The last element is the '\0' character.
1431*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 2]), strchr(reinterpret_cast<char*>(buf),
1432*8d67ca89SAndroid Build Coastguard Worker search_value));
1433*8d67ca89SAndroid Build Coastguard Worker }
1434*8d67ca89SAndroid Build Coastguard Worker }
1435*8d67ca89SAndroid Build Coastguard Worker }
1436*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strchr_align)1437*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strchr_align) {
1438*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferAlignTest(MEDIUM, DoStrchrTest);
1439*8d67ca89SAndroid Build Coastguard Worker }
1440*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strchr_overread)1441*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strchr_overread) {
1442*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferOverreadTest(DoStrchrTest);
1443*8d67ca89SAndroid Build Coastguard Worker }
1444*8d67ca89SAndroid Build Coastguard Worker
DoStrrchrTest(uint8_t * buf,size_t len)1445*8d67ca89SAndroid Build Coastguard Worker static void DoStrrchrTest(uint8_t* buf, size_t len) {
1446*8d67ca89SAndroid Build Coastguard Worker if (len >= 1) {
1447*8d67ca89SAndroid Build Coastguard Worker char value = 32 + (len % 96);
1448*8d67ca89SAndroid Build Coastguard Worker char search_value = 33 + (len % 96);
1449*8d67ca89SAndroid Build Coastguard Worker memset(buf, value, len - 1);
1450*8d67ca89SAndroid Build Coastguard Worker buf[len - 1] = '\0';
1451*8d67ca89SAndroid Build Coastguard Worker // The buffer does not contain the search value.
1452*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, strrchr(reinterpret_cast<char*>(buf), search_value));
1453*8d67ca89SAndroid Build Coastguard Worker // Search for the special '\0' character.
1454*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 1]), strrchr(reinterpret_cast<char*>(buf), '\0'));
1455*8d67ca89SAndroid Build Coastguard Worker if (len >= 2) {
1456*8d67ca89SAndroid Build Coastguard Worker buf[0] = search_value;
1457*8d67ca89SAndroid Build Coastguard Worker // The search value is the first element in the buffer.
1458*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strrchr(reinterpret_cast<char*>(buf),
1459*8d67ca89SAndroid Build Coastguard Worker search_value));
1460*8d67ca89SAndroid Build Coastguard Worker
1461*8d67ca89SAndroid Build Coastguard Worker buf[0] = value;
1462*8d67ca89SAndroid Build Coastguard Worker buf[len - 2] = search_value;
1463*8d67ca89SAndroid Build Coastguard Worker // The search value is the second to last element in the buffer.
1464*8d67ca89SAndroid Build Coastguard Worker // The last element is the '\0' character.
1465*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 2]), strrchr(reinterpret_cast<char*>(buf),
1466*8d67ca89SAndroid Build Coastguard Worker search_value));
1467*8d67ca89SAndroid Build Coastguard Worker }
1468*8d67ca89SAndroid Build Coastguard Worker }
1469*8d67ca89SAndroid Build Coastguard Worker }
1470*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strrchr_align)1471*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strrchr_align) {
1472*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferAlignTest(MEDIUM, DoStrrchrTest);
1473*8d67ca89SAndroid Build Coastguard Worker }
1474*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strrchr_overread)1475*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strrchr_overread) {
1476*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferOverreadTest(DoStrrchrTest);
1477*8d67ca89SAndroid Build Coastguard Worker }
1478*8d67ca89SAndroid Build Coastguard Worker
1479*8d67ca89SAndroid Build Coastguard Worker #if !defined(ANDROID_HOST_MUSL)
TestBasename(const char * in,const char * expected_out)1480*8d67ca89SAndroid Build Coastguard Worker static void TestBasename(const char* in, const char* expected_out) {
1481*8d67ca89SAndroid Build Coastguard Worker errno = 0;
1482*8d67ca89SAndroid Build Coastguard Worker const char* out = basename(in);
1483*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(expected_out, out) << in;
1484*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(0) << in;
1485*8d67ca89SAndroid Build Coastguard Worker }
1486*8d67ca89SAndroid Build Coastguard Worker #endif
1487*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,__gnu_basename)1488*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, __gnu_basename) {
1489*8d67ca89SAndroid Build Coastguard Worker #if !defined(ANDROID_HOST_MUSL)
1490*8d67ca89SAndroid Build Coastguard Worker TestBasename("", "");
1491*8d67ca89SAndroid Build Coastguard Worker TestBasename("/usr/lib", "lib");
1492*8d67ca89SAndroid Build Coastguard Worker TestBasename("/usr/", "");
1493*8d67ca89SAndroid Build Coastguard Worker TestBasename("usr", "usr");
1494*8d67ca89SAndroid Build Coastguard Worker TestBasename("/", "");
1495*8d67ca89SAndroid Build Coastguard Worker TestBasename(".", ".");
1496*8d67ca89SAndroid Build Coastguard Worker TestBasename("..", "..");
1497*8d67ca89SAndroid Build Coastguard Worker TestBasename("///", "");
1498*8d67ca89SAndroid Build Coastguard Worker TestBasename("//usr//lib//", "");
1499*8d67ca89SAndroid Build Coastguard Worker #else
1500*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "musl doesn't have GNU basename";
1501*8d67ca89SAndroid Build Coastguard Worker #endif
1502*8d67ca89SAndroid Build Coastguard Worker }
1503*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strnlen_147048)1504*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strnlen_147048) {
1505*8d67ca89SAndroid Build Coastguard Worker // https://code.google.com/p/android/issues/detail?id=147048
1506*8d67ca89SAndroid Build Coastguard Worker char stack_src[64] = {0};
1507*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(0U, strnlen(stack_src, 1024*1024*1024));
1508*8d67ca89SAndroid Build Coastguard Worker char* heap_src = new char[1];
1509*8d67ca89SAndroid Build Coastguard Worker *heap_src = '\0';
1510*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(0U, strnlen(heap_src, 1024*1024*1024));
1511*8d67ca89SAndroid Build Coastguard Worker delete[] heap_src;
1512*8d67ca89SAndroid Build Coastguard Worker }
1513*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strnlen_74741)1514*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strnlen_74741) {
1515*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(4U, strnlen("test", SIZE_MAX));
1516*8d67ca89SAndroid Build Coastguard Worker }
1517*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,mempcpy)1518*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, mempcpy) {
1519*8d67ca89SAndroid Build Coastguard Worker char dst[6];
1520*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(&dst[4], reinterpret_cast<char*>(mempcpy(dst, "hello", 4)));
1521*8d67ca89SAndroid Build Coastguard Worker }
1522*8d67ca89SAndroid Build Coastguard Worker
1523*8d67ca89SAndroid Build Coastguard Worker // clang depends on the fact that a memcpy where src and dst is the same
1524*8d67ca89SAndroid Build Coastguard Worker // still operates correctly. This test verifies that this assumption
1525*8d67ca89SAndroid Build Coastguard Worker // holds true.
1526*8d67ca89SAndroid Build Coastguard Worker // See https://llvm.org/bugs/show_bug.cgi?id=11763 for more information.
1527*8d67ca89SAndroid Build Coastguard Worker static std::vector<uint8_t> g_memcpy_same_buffer;
1528*8d67ca89SAndroid Build Coastguard Worker
DoMemcpySameTest(uint8_t * buffer,size_t len)1529*8d67ca89SAndroid Build Coastguard Worker static void DoMemcpySameTest(uint8_t* buffer, size_t len) {
1530*8d67ca89SAndroid Build Coastguard Worker memcpy(buffer, g_memcpy_same_buffer.data(), len);
1531*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(buffer, memcpy(buffer, buffer, len));
1532*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(buffer, g_memcpy_same_buffer.data(), len) == 0);
1533*8d67ca89SAndroid Build Coastguard Worker }
1534*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memcpy_src_dst_same)1535*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memcpy_src_dst_same) {
1536*8d67ca89SAndroid Build Coastguard Worker g_memcpy_same_buffer.resize(MEDIUM);
1537*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < MEDIUM; i++) {
1538*8d67ca89SAndroid Build Coastguard Worker g_memcpy_same_buffer[i] = i;
1539*8d67ca89SAndroid Build Coastguard Worker }
1540*8d67ca89SAndroid Build Coastguard Worker RunSingleBufferAlignTest(MEDIUM, DoMemcpySameTest);
1541*8d67ca89SAndroid Build Coastguard Worker }
1542*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memmem_strstr_empty_needle)1543*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memmem_strstr_empty_needle) {
1544*8d67ca89SAndroid Build Coastguard Worker const char* some_haystack = "haystack";
1545*8d67ca89SAndroid Build Coastguard Worker const char* empty_haystack = "";
1546*8d67ca89SAndroid Build Coastguard Worker
1547*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(some_haystack, memmem(some_haystack, 8, "", 0));
1548*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(empty_haystack, memmem(empty_haystack, 0, "", 0));
1549*8d67ca89SAndroid Build Coastguard Worker
1550*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(some_haystack, strstr(some_haystack, ""));
1551*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(empty_haystack, strstr(empty_haystack, ""));
1552*8d67ca89SAndroid Build Coastguard Worker }
1553*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memmem_smoke)1554*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memmem_smoke) {
1555*8d67ca89SAndroid Build Coastguard Worker const char haystack[] = "big\0daddy/giant\0haystacks!";
1556*8d67ca89SAndroid Build Coastguard Worker
1557*8d67ca89SAndroid Build Coastguard Worker // The current memmem() implementation has special cases for needles of
1558*8d67ca89SAndroid Build Coastguard Worker // lengths 0, 1, 2, 3, and 4, plus a long needle case. We test matches at the
1559*8d67ca89SAndroid Build Coastguard Worker // beginning, middle, and end of the haystack.
1560*8d67ca89SAndroid Build Coastguard Worker
1561*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "", 0));
1562*8d67ca89SAndroid Build Coastguard Worker
1563*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "b", 1));
1564*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "bi", 2));
1565*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big", 3));
1566*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big\0", 4));
1567*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big\0d", 5));
1568*8d67ca89SAndroid Build Coastguard Worker
1569*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 2, memmem(haystack, sizeof(haystack), "g", 1));
1570*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gi", 2));
1571*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gia", 3));
1572*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gian", 4));
1573*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "giant", 5));
1574*8d67ca89SAndroid Build Coastguard Worker
1575*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 25, memmem(haystack, sizeof(haystack), "!", 1));
1576*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 24, memmem(haystack, sizeof(haystack), "s!", 2));
1577*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 23, memmem(haystack, sizeof(haystack), "ks!", 3));
1578*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 22, memmem(haystack, sizeof(haystack), "cks!", 4));
1579*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 21, memmem(haystack, sizeof(haystack), "acks!", 5));
1580*8d67ca89SAndroid Build Coastguard Worker }
1581*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strstr_smoke)1582*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strstr_smoke) {
1583*8d67ca89SAndroid Build Coastguard Worker const char* haystack = "big daddy/giant haystacks!";
1584*8d67ca89SAndroid Build Coastguard Worker
1585*8d67ca89SAndroid Build Coastguard Worker // The current strstr() implementation has special cases for needles of
1586*8d67ca89SAndroid Build Coastguard Worker // lengths 0, 1, 2, 3, and 4, plus a long needle case. We test matches at the
1587*8d67ca89SAndroid Build Coastguard Worker // beginning, middle, and end of the haystack.
1588*8d67ca89SAndroid Build Coastguard Worker
1589*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, strstr(haystack, ""));
1590*8d67ca89SAndroid Build Coastguard Worker
1591*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, strstr(haystack, "b"));
1592*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, strstr(haystack, "bi"));
1593*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, strstr(haystack, "big"));
1594*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, strstr(haystack, "big "));
1595*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, strstr(haystack, "big d"));
1596*8d67ca89SAndroid Build Coastguard Worker
1597*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 2, strstr(haystack, "g"));
1598*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 10, strstr(haystack, "gi"));
1599*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 10, strstr(haystack, "gia"));
1600*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 10, strstr(haystack, "gian"));
1601*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 10, strstr(haystack, "giant"));
1602*8d67ca89SAndroid Build Coastguard Worker
1603*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 25, strstr(haystack, "!"));
1604*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 24, strstr(haystack, "s!"));
1605*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 23, strstr(haystack, "ks!"));
1606*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 22, strstr(haystack, "cks!"));
1607*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 21, strstr(haystack, "acks!"));
1608*8d67ca89SAndroid Build Coastguard Worker }
1609*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcasestr_smoke)1610*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcasestr_smoke) {
1611*8d67ca89SAndroid Build Coastguard Worker const char* haystack = "bIg dAdDy/gIaNt hAyStAcKs";
1612*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack, strcasestr(haystack, ""));
1613*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 0, strcasestr(haystack, "B"));
1614*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 1, strcasestr(haystack, "i"));
1615*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(haystack + 4, strcasestr(haystack, "Da"));
1616*8d67ca89SAndroid Build Coastguard Worker }
1617*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcoll_smoke)1618*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcoll_smoke) {
1619*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strcoll("aab", "aac") < 0);
1620*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strcoll("aab", "aab") == 0);
1621*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strcoll("aac", "aab") > 0);
1622*8d67ca89SAndroid Build Coastguard Worker }
1623*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strcoll_l_smoke)1624*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strcoll_l_smoke) {
1625*8d67ca89SAndroid Build Coastguard Worker // bionic just forwards to strcoll(3).
1626*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strcoll_l("aab", "aac", LC_GLOBAL_LOCALE) < 0);
1627*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strcoll_l("aab", "aab", LC_GLOBAL_LOCALE) == 0);
1628*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strcoll_l("aac", "aab", LC_GLOBAL_LOCALE) > 0);
1629*8d67ca89SAndroid Build Coastguard Worker }
1630*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strxfrm_smoke)1631*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strxfrm_smoke) {
1632*8d67ca89SAndroid Build Coastguard Worker const char* src1 = "aab";
1633*8d67ca89SAndroid Build Coastguard Worker char dst1[16] = {};
1634*8d67ca89SAndroid Build Coastguard Worker // Dry run.
1635*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(strxfrm(dst1, src1, 0), 3U);
1636*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(dst1, "");
1637*8d67ca89SAndroid Build Coastguard Worker // Really do it.
1638*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(strxfrm(dst1, src1, sizeof(dst1)), 3U);
1639*8d67ca89SAndroid Build Coastguard Worker
1640*8d67ca89SAndroid Build Coastguard Worker const char* src2 = "aac";
1641*8d67ca89SAndroid Build Coastguard Worker char dst2[16] = {};
1642*8d67ca89SAndroid Build Coastguard Worker // Dry run.
1643*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(strxfrm(dst2, src2, 0), 3U);
1644*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(dst2, "");
1645*8d67ca89SAndroid Build Coastguard Worker // Really do it.
1646*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(strxfrm(dst2, src2, sizeof(dst2)), 3U);
1647*8d67ca89SAndroid Build Coastguard Worker
1648*8d67ca89SAndroid Build Coastguard Worker // The "transform" of two different strings should cause different outputs.
1649*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(strcmp(dst1, dst2) < 0);
1650*8d67ca89SAndroid Build Coastguard Worker }
1651*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strxfrm_l_smoke)1652*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strxfrm_l_smoke) {
1653*8d67ca89SAndroid Build Coastguard Worker // bionic just forwards to strxfrm(3), so this is a subset of the
1654*8d67ca89SAndroid Build Coastguard Worker // strxfrm test.
1655*8d67ca89SAndroid Build Coastguard Worker const char* src1 = "aab";
1656*8d67ca89SAndroid Build Coastguard Worker char dst1[16] = {};
1657*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(strxfrm_l(dst1, src1, 0, LC_GLOBAL_LOCALE), 3U);
1658*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(dst1, "");
1659*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(strxfrm_l(dst1, src1, sizeof(dst1), LC_GLOBAL_LOCALE), 3U);
1660*8d67ca89SAndroid Build Coastguard Worker }
1661*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memccpy_smoke)1662*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memccpy_smoke) {
1663*8d67ca89SAndroid Build Coastguard Worker char dst[32];
1664*8d67ca89SAndroid Build Coastguard Worker
1665*8d67ca89SAndroid Build Coastguard Worker memset(dst, 0, sizeof(dst));
1666*8d67ca89SAndroid Build Coastguard Worker char* p = static_cast<char*>(memccpy(dst, "hello world", ' ', 32));
1667*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("hello ", dst);
1668*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(ptrdiff_t(6), p - dst);
1669*8d67ca89SAndroid Build Coastguard Worker
1670*8d67ca89SAndroid Build Coastguard Worker memset(dst, 0, sizeof(dst));
1671*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, memccpy(dst, "hello world", ' ', 4));
1672*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("hell", dst);
1673*8d67ca89SAndroid Build Coastguard Worker }
1674*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,memset_explicit_smoke)1675*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, memset_explicit_smoke) {
1676*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1677*8d67ca89SAndroid Build Coastguard Worker // We can't reliably test that the compiler won't optimize out calls to
1678*8d67ca89SAndroid Build Coastguard Worker // memset_explicit(), but we can at least check that it behaves like memset.
1679*8d67ca89SAndroid Build Coastguard Worker char buf[32];
1680*8d67ca89SAndroid Build Coastguard Worker memset_explicit(buf, 'x', sizeof(buf));
1681*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memcmp(buf, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", sizeof(buf)) == 0);
1682*8d67ca89SAndroid Build Coastguard Worker #else
1683*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "memset_explicit not available";
1684*8d67ca89SAndroid Build Coastguard Worker #endif
1685*8d67ca89SAndroid Build Coastguard Worker }
1686*8d67ca89SAndroid Build Coastguard Worker
TEST(STRING_TEST,strerrorname_np)1687*8d67ca89SAndroid Build Coastguard Worker TEST(STRING_TEST, strerrorname_np) {
1688*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1689*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("0", strerrorname_np(0));
1690*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("EINVAL", strerrorname_np(EINVAL));
1691*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("ENOSYS", strerrorname_np(ENOSYS));
1692*8d67ca89SAndroid Build Coastguard Worker
1693*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, strerrorname_np(-1));
1694*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, strerrorname_np(666));
1695*8d67ca89SAndroid Build Coastguard Worker #else
1696*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "strerrorname_np not available";
1697*8d67ca89SAndroid Build Coastguard Worker #endif
1698*8d67ca89SAndroid Build Coastguard Worker }
1699