blob: f1ac9ddb4057a4819af61bfa3858b47c5c4e928a [file] [log] [blame]
Irina Tirdeab5f053b2012-09-08 09:17:54 +03001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18
19#include <errno.h>
Dan Alberte5fdaa42014-06-14 01:04:31 +000020#include <malloc.h>
Anna Tikhonova036154b2012-10-05 15:21:11 +040021#include <math.h>
Irina Tirdeab5f053b2012-09-08 09:17:54 +030022#include <string.h>
23
Christopher Ferrisb687ad32013-11-06 17:32:11 -080024#include "buffer_tests.h"
25
Anna Tikhonova036154b2012-10-05 15:21:11 +040026#define KB 1024
27#define SMALL 1*KB
Christopher Ferrisb687ad32013-11-06 17:32:11 -080028#define MEDIUM 4*KB
Anna Tikhonova036154b2012-10-05 15:21:11 +040029#define LARGE 64*KB
30
31static int signum(int i) {
32 if (i < 0) {
33 return -1;
34 } else if (i > 0) {
35 return 1;
36 }
37 return 0;
38}
39
Irina Tirdeab5f053b2012-09-08 09:17:54 +030040TEST(string, strerror) {
41 // Valid.
42 ASSERT_STREQ("Success", strerror(0));
43 ASSERT_STREQ("Operation not permitted", strerror(1));
44
45 // Invalid.
Elliott Hughese6e60062013-01-10 16:01:59 -080046 ASSERT_STREQ("Unknown error -1", strerror(-1));
Irina Tirdeab5f053b2012-09-08 09:17:54 +030047 ASSERT_STREQ("Unknown error 1234", strerror(1234));
48}
49
Christopher Ferrisf04935c2013-12-20 18:43:21 -080050#if defined(__BIONIC__)
Elliott Hughesad88a082012-10-24 18:37:21 -070051static void* ConcurrentStrErrorFn(void*) {
Irina Tirdeab5f053b2012-09-08 09:17:54 +030052 bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
53 return reinterpret_cast<void*>(equal);
54}
Christopher Ferrisf04935c2013-12-20 18:43:21 -080055#endif // __BIONIC__
Irina Tirdeab5f053b2012-09-08 09:17:54 +030056
Christopher Ferrisf04935c2013-12-20 18:43:21 -080057// glibc's strerror isn't thread safe, only its strsignal.
Irina Tirdeab5f053b2012-09-08 09:17:54 +030058TEST(string, strerror_concurrent) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -080059#if defined(__BIONIC__)
Irina Tirdeab5f053b2012-09-08 09:17:54 +030060 const char* strerror1001 = strerror(1001);
61 ASSERT_STREQ("Unknown error 1001", strerror1001);
62
63 pthread_t t;
64 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL));
65 void* result;
66 ASSERT_EQ(0, pthread_join(t, &result));
67 ASSERT_TRUE(static_cast<bool>(result));
68
69 ASSERT_STREQ("Unknown error 1001", strerror1001);
Christopher Ferrisf04935c2013-12-20 18:43:21 -080070#else // __BIONIC__
71 GTEST_LOG_(INFO) << "This test does nothing.\n";
72#endif // __BIONIC__
Irina Tirdeab5f053b2012-09-08 09:17:54 +030073}
Elliott Hughesad88a082012-10-24 18:37:21 -070074
Irina Tirdeab5f053b2012-09-08 09:17:54 +030075TEST(string, strerror_r) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -080076#if defined(__BIONIC__) // glibc's strerror_r doesn't even have the same signature as the POSIX one.
Irina Tirdeab5f053b2012-09-08 09:17:54 +030077 char buf[256];
78
79 // Valid.
80 ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf)));
81 ASSERT_STREQ("Success", buf);
82 ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf)));
83 ASSERT_STREQ("Operation not permitted", buf);
84
85 // Invalid.
86 ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf)));
Nick Kralevich60605892013-01-15 10:35:09 -080087 ASSERT_STREQ("Unknown error -1", buf);
Irina Tirdeab5f053b2012-09-08 09:17:54 +030088 ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf)));
89 ASSERT_STREQ("Unknown error 1234", buf);
90
91 // Buffer too small.
92 ASSERT_EQ(-1, strerror_r(0, buf, 2));
93 ASSERT_EQ(ERANGE, errno);
Christopher Ferrisf04935c2013-12-20 18:43:21 -080094#else // __BIONIC__
95 GTEST_LOG_(INFO) << "This test does nothing.\n";
96#endif // __BIONIC__
Irina Tirdeab5f053b2012-09-08 09:17:54 +030097}
Irina Tirdeab5f053b2012-09-08 09:17:54 +030098
99TEST(string, strsignal) {
100 // A regular signal.
101 ASSERT_STREQ("Hangup", strsignal(1));
102
103 // A real-time signal.
Elliott Hughes0990d4f2014-04-30 09:45:40 -0700104 ASSERT_STREQ("Real-time signal 14", strsignal(SIGRTMIN + 14));
105 // One of the signals the C library keeps to itself.
106 ASSERT_STREQ("Unknown signal 32", strsignal(__SIGRTMIN));
Irina Tirdeab5f053b2012-09-08 09:17:54 +0300107
108 // Errors.
109 ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
110 ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small.
111 ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large.
112}
113
Elliott Hughesad88a082012-10-24 18:37:21 -0700114static void* ConcurrentStrSignalFn(void*) {
Irina Tirdeab5f053b2012-09-08 09:17:54 +0300115 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
116 return reinterpret_cast<void*>(equal);
117}
118
119TEST(string, strsignal_concurrent) {
120 const char* strsignal1001 = strsignal(1001);
121 ASSERT_STREQ("Unknown signal 1001", strsignal1001);
122
123 pthread_t t;
124 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL));
125 void* result;
126 ASSERT_EQ(0, pthread_join(t, &result));
127 ASSERT_TRUE(static_cast<bool>(result));
128
129 ASSERT_STREQ("Unknown signal 1001", strsignal1001);
130}
Anna Tikhonova036154b2012-10-05 15:21:11 +0400131
132// TODO: where did these numbers come from?
133#define POS_ITER 10
134#define ITER 500
135
136// For every length we want to test, vary and change alignment
137// of allocated memory, fill it with some values, calculate
138// expected result and then run function and compare what we got.
139// These tests contributed by Intel Corporation.
140// TODO: make these tests more intention-revealing and less random.
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400141template<class Character>
Anna Tikhonova036154b2012-10-05 15:21:11 +0400142struct StringTestState {
143 StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) {
144 int max_alignment = 64;
145
146 // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
Dan Alberte5fdaa42014-06-14 01:04:31 +0000147 glob_ptr = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
148 glob_ptr1 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
149 glob_ptr2 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400150
151 InitLenArray();
152
153 srandom(1234);
154 }
155
156 ~StringTestState() {
157 free(glob_ptr);
158 free(glob_ptr1);
159 free(glob_ptr2);
160 }
161
162 void NewIteration() {
163 int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 };
164 int usable_alignments = 10;
165 int align1 = alignments[random() % (usable_alignments - 1)];
166 int align2 = alignments[random() % (usable_alignments - 1)];
167
168 ptr = glob_ptr + align1;
169 ptr1 = glob_ptr1 + align1;
170 ptr2 = glob_ptr2 + align2;
171 }
172
173 const size_t MAX_LEN;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400174 Character *ptr, *ptr1, *ptr2;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400175 size_t n;
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700176 size_t len[ITER + 1];
Anna Tikhonova036154b2012-10-05 15:21:11 +0400177
178 private:
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400179 Character *glob_ptr, *glob_ptr1, *glob_ptr2;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400180
181 // Calculate input lengths and fill state.len with them.
182 // Test small lengths with more density than big ones. Manually push
183 // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
184 // Return number of lengths to test.
185 void InitLenArray() {
186 n = 0;
187 len[n++] = 0;
188 for (size_t i = 1; i < ITER; ++i) {
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700189 size_t l = static_cast<size_t>(exp(log(static_cast<double>(MAX_LEN)) * i / ITER));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400190 if (l != len[n - 1]) {
191 len[n++] = l;
192 }
193 }
194 len[n++] = MAX_LEN;
195 }
196};
197
198TEST(string, strcat) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400199 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400200 for (size_t i = 1; i < state.n; i++) {
201 for (size_t j = 0; j < POS_ITER; j++) {
202 state.NewIteration();
203
204 memset(state.ptr2, '\2', state.MAX_LEN);
205 state.ptr2[state.MAX_LEN - 1] = '\0';
206 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
207
208 memset(state.ptr1, random() & 255, state.len[i]);
209 state.ptr1[random() % state.len[i]] = '\0';
210 state.ptr1[state.len[i] - 1] = '\0';
211
212 strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
213
214 EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
215 EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
216 }
217 }
218}
219
Nick Kralevich13476de2013-06-03 10:58:06 -0700220// one byte target with "\0" source
221TEST(string, strcpy2) {
222 char buf[1];
223 char* orig = strdup("");
Christopher Ferris950a58e2014-04-04 14:38:18 -0700224 ASSERT_EQ(buf, strcpy(buf, orig));
Nick Kralevich13476de2013-06-03 10:58:06 -0700225 ASSERT_EQ('\0', buf[0]);
226 free(orig);
227}
228
229// multibyte target where we under fill target
230TEST(string, strcpy3) {
231 char buf[10];
232 char* orig = strdup("12345");
233 memset(buf, 'A', sizeof(buf));
Christopher Ferris950a58e2014-04-04 14:38:18 -0700234 ASSERT_EQ(buf, strcpy(buf, orig));
235 ASSERT_STREQ("12345", buf);
Nick Kralevich13476de2013-06-03 10:58:06 -0700236 ASSERT_EQ('A', buf[6]);
237 ASSERT_EQ('A', buf[7]);
238 ASSERT_EQ('A', buf[8]);
239 ASSERT_EQ('A', buf[9]);
240 free(orig);
241}
242
243// multibyte target where we fill target exactly
244TEST(string, strcpy4) {
245 char buf[10];
246 char* orig = strdup("123456789");
247 memset(buf, 'A', sizeof(buf));
Christopher Ferris950a58e2014-04-04 14:38:18 -0700248 ASSERT_EQ(buf, strcpy(buf, orig));
249 ASSERT_STREQ("123456789", buf);
250 free(orig);
251}
252
253// one byte target with "\0" source
254TEST(string, stpcpy2) {
255 char buf[1];
256 char* orig = strdup("");
257 ASSERT_EQ(buf, stpcpy(buf, orig));
258 ASSERT_EQ('\0', buf[0]);
259 free(orig);
260}
261
262// multibyte target where we under fill target
263TEST(string, stpcpy3) {
264 char buf[10];
265 char* orig = strdup("12345");
266 memset(buf, 'A', sizeof(buf));
267 ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
268 ASSERT_STREQ("12345", buf);
269 ASSERT_EQ('A', buf[6]);
270 ASSERT_EQ('A', buf[7]);
271 ASSERT_EQ('A', buf[8]);
272 ASSERT_EQ('A', buf[9]);
273 free(orig);
274}
275
276// multibyte target where we fill target exactly
277TEST(string, stpcpy4) {
278 char buf[10];
279 char* orig = strdup("123456789");
280 memset(buf, 'A', sizeof(buf));
281 ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
282 ASSERT_STREQ("123456789", buf);
Nick Kralevich13476de2013-06-03 10:58:06 -0700283 free(orig);
284}
285
Nick Kralevichcf870192013-05-30 16:48:53 -0700286TEST(string, strcat2) {
287 char buf[10];
288 memset(buf, 'A', sizeof(buf));
289 buf[0] = 'a';
290 buf[1] = '\0';
291 char* res = strcat(buf, "01234");
292 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700293 ASSERT_STREQ("a01234", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700294 ASSERT_EQ('A', buf[7]);
295 ASSERT_EQ('A', buf[8]);
296 ASSERT_EQ('A', buf[9]);
297}
298
299TEST(string, strcat3) {
300 char buf[10];
301 memset(buf, 'A', sizeof(buf));
302 buf[0] = 'a';
303 buf[1] = '\0';
304 char* res = strcat(buf, "01234567");
305 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700306 ASSERT_STREQ("a01234567", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700307}
308
309TEST(string, strncat2) {
310 char buf[10];
311 memset(buf, 'A', sizeof(buf));
312 buf[0] = 'a';
313 buf[1] = '\0';
314 char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1);
315 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700316 ASSERT_STREQ("a01234", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700317 ASSERT_EQ('A', buf[7]);
318 ASSERT_EQ('A', buf[8]);
319 ASSERT_EQ('A', buf[9]);
320}
321
322TEST(string, strncat3) {
323 char buf[10];
324 memset(buf, 'A', sizeof(buf));
325 buf[0] = 'a';
326 buf[1] = '\0';
327 char* res = strncat(buf, "0123456789", 5);
328 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700329 ASSERT_STREQ("a01234", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700330 ASSERT_EQ('A', buf[7]);
331 ASSERT_EQ('A', buf[8]);
332 ASSERT_EQ('A', buf[9]);
333}
334
335TEST(string, strncat4) {
336 char buf[10];
337 memset(buf, 'A', sizeof(buf));
338 buf[0] = 'a';
339 buf[1] = '\0';
340 char* res = strncat(buf, "01234567", 8);
341 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700342 ASSERT_STREQ("a01234567", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700343}
344
345TEST(string, strncat5) {
346 char buf[10];
347 memset(buf, 'A', sizeof(buf));
348 buf[0] = 'a';
349 buf[1] = '\0';
350 char* res = strncat(buf, "01234567", 9);
351 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700352 ASSERT_STREQ("a01234567", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700353}
354
Nick Kralevich4f40e512013-04-19 16:54:22 -0700355TEST(string, strchr_with_0) {
356 char buf[10];
357 const char* s = "01234";
358 memcpy(buf, s, strlen(s) + 1);
359 EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
360}
361
Christopher Ferris3a657d02014-06-27 12:33:22 -0700362TEST(string, strchr_multiple) {
363 char str[128];
364 memset(str, 'a', sizeof(str) - 1);
365 str[sizeof(str)-1] = '\0';
366
367 // Verify that strchr finds the first occurrence of 'a' in a string
368 // filled with 'a' characters. Iterate over the string putting
369 // non 'a' characters at the front of the string during each iteration
370 // and continue to verify that strchr can find the first occurrence
371 // properly. The idea is to cover all possible alignments of the location
372 // of the first occurrence of the 'a' character and which includes
373 // other 'a' characters close by.
374 for (size_t i = 0; i < sizeof(str) - 1; i++) {
375 EXPECT_EQ(&str[i], strchr(str, 'a'));
376 str[i] = 'b';
377 }
378}
379
Anna Tikhonova036154b2012-10-05 15:21:11 +0400380TEST(string, strchr) {
381 int seek_char = random() & 255;
382
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400383 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400384 for (size_t i = 1; i < state.n; i++) {
385 for (size_t j = 0; j < POS_ITER; j++) {
386 state.NewIteration();
387
388 if (~seek_char > 0) {
389 memset(state.ptr1, ~seek_char, state.len[i]);
390 } else {
391 memset(state.ptr1, '\1', state.len[i]);
392 }
393 state.ptr1[state.len[i] - 1] = '\0';
394
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700395 size_t pos = random() % state.MAX_LEN;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400396 char* expected;
397 if (pos >= state.len[i] - 1) {
398 if (seek_char == 0) {
399 expected = state.ptr1 + state.len[i] - 1;
400 } else {
401 expected = NULL;
402 }
403 } else {
404 state.ptr1[pos] = seek_char;
405 expected = state.ptr1 + pos;
406 }
407
408 ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
409 }
410 }
411}
412
413TEST(string, strcmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400414 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400415 for (size_t i = 1; i < state.n; i++) {
416 for (size_t j = 0; j < POS_ITER; j++) {
417 state.NewIteration();
418
419 memset(state.ptr1, 'v', state.MAX_LEN);
420 memset(state.ptr2, 'n', state.MAX_LEN);
421 state.ptr1[state.len[i] - 1] = '\0';
422 state.ptr2[state.len[i] - 1] = '\0';
423
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700424 size_t pos = 1 + (random() % (state.MAX_LEN - 1));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400425 int actual;
426 int expected;
427 if (pos >= state.len[i] - 1) {
428 memcpy(state.ptr1, state.ptr2, state.len[i]);
429 expected = 0;
430 actual = strcmp(state.ptr1, state.ptr2);
431 } else {
432 memcpy(state.ptr1, state.ptr2, pos);
433 if (state.ptr1[pos] > state.ptr2[pos]) {
434 expected = 1;
435 } else if (state.ptr1[pos] == state.ptr2[pos]) {
436 state.ptr1[pos + 1] = '\0';
437 state.ptr2[pos + 1] = '\0';
438 expected = 0;
439 } else {
440 expected = -1;
441 }
442 actual = strcmp(state.ptr1, state.ptr2);
443 }
444
445 ASSERT_EQ(expected, signum(actual));
446 }
447 }
448}
449
Christopher Ferris950a58e2014-04-04 14:38:18 -0700450TEST(string, stpcpy) {
451 StringTestState<char> state(SMALL);
452 for (size_t j = 0; j < POS_ITER; j++) {
453 state.NewIteration();
454
455 size_t pos = random() % state.MAX_LEN;
456
457 memset(state.ptr1, '\2', pos);
458 state.ptr1[pos] = '\0';
459 state.ptr1[state.MAX_LEN - 1] = '\0';
460
461 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
462
463 memset(state.ptr2, '\1', state.MAX_LEN);
464 state.ptr2[state.MAX_LEN - 1] = '\0';
465
466 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
467 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
468 state.ptr[2 * state.MAX_LEN - 1] = '\0';
469
470 ASSERT_TRUE(stpcpy(state.ptr2, state.ptr1) == state.ptr2 + strlen(state.ptr1));
471 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
472 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
473 }
474}
475
Anna Tikhonova036154b2012-10-05 15:21:11 +0400476TEST(string, strcpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400477 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400478 for (size_t j = 0; j < POS_ITER; j++) {
479 state.NewIteration();
480
481 size_t pos = random() % state.MAX_LEN;
482
483 memset(state.ptr1, '\2', pos);
484 state.ptr1[pos] = '\0';
485 state.ptr1[state.MAX_LEN - 1] = '\0';
486
487 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
488
489 memset(state.ptr2, '\1', state.MAX_LEN);
490 state.ptr2[state.MAX_LEN - 1] = '\0';
491
492 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
493 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
494 state.ptr[2 * state.MAX_LEN - 1] = '\0';
495
496 ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
497 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
498 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
499 }
500}
501
Anna Tikhonova036154b2012-10-05 15:21:11 +0400502TEST(string, strlcat) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800503#if defined(__BIONIC__)
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400504 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400505 for (size_t i = 0; i < state.n; i++) {
506 for (size_t j = 0; j < POS_ITER; j++) {
507 state.NewIteration();
508
509 memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
510 state.ptr2[state.MAX_LEN - 1] = '\0';
511 memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
512
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700513 size_t pos = random() % state.MAX_LEN;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400514 memset(state.ptr1, '\3', pos);
515 state.ptr1[pos] = '\0';
516 if (pos < state.len[i]) {
517 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
518 } else {
519 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
520 state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
521 }
522
523 strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
524
525 ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
526 }
527 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800528#else // __BIONIC__
529 GTEST_LOG_(INFO) << "This test does nothing.\n";
530#endif // __BIONIC__
Anna Tikhonova036154b2012-10-05 15:21:11 +0400531}
Anna Tikhonova036154b2012-10-05 15:21:11 +0400532
Anna Tikhonova036154b2012-10-05 15:21:11 +0400533TEST(string, strlcpy) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800534#if defined(__BIONIC__)
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400535 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400536 for (size_t j = 0; j < POS_ITER; j++) {
537 state.NewIteration();
538
539 int rand = random() & 255;
540 if (rand < 1) {
541 rand = 1;
542 }
543 memset(state.ptr1, rand, state.MAX_LEN);
544
545 size_t pos = random() % state.MAX_LEN;
546 if (pos < state.MAX_LEN) {
547 state.ptr1[pos] = '\0';
548 }
549 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
550
551 memset(state.ptr2, random() & 255, state.MAX_LEN);
552 memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
553
554 if (pos > state.MAX_LEN - 1) {
555 memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
556 state.ptr[2 * state.MAX_LEN - 1] = '\0';
557 } else {
558 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
559 }
560
561 ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
562 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
563 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
564 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800565#else // __BIONIC__
566 GTEST_LOG_(INFO) << "This test does nothing.\n";
567#endif // __BIONIC__
Anna Tikhonova036154b2012-10-05 15:21:11 +0400568}
Anna Tikhonova036154b2012-10-05 15:21:11 +0400569
570TEST(string, strncat) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400571 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400572 for (size_t i = 1; i < state.n; i++) {
573 for (size_t j = 0; j < POS_ITER; j++) {
574 state.NewIteration();
575
576 memset(state.ptr2, '\2', state.MAX_LEN);
577 state.ptr2[state.MAX_LEN - 1] = '\0';
578 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
579
580 memset(state.ptr1, random() & 255, state.len[i]);
581 state.ptr1[random() % state.len[i]] = '\0';
582 state.ptr1[state.len[i] - 1] = '\0';
583
584 size_t pos = strlen(state.ptr1);
585
586 size_t actual = random() % state.len[i];
587 strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
588 state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
589
590 ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
591 ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
592 }
593 }
594}
595
596TEST(string, strncmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400597 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400598 for (size_t i = 1; i < state.n; i++) {
599 for (size_t j = 0; j < POS_ITER; j++) {
600 state.NewIteration();
601
602 memset(state.ptr1, 'v', state.MAX_LEN);
603 memset(state.ptr2, 'n', state.MAX_LEN);
604 state.ptr1[state.len[i] - 1] = '\0';
605 state.ptr2[state.len[i] - 1] = '\0';
606
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700607 size_t pos = 1 + (random() % (state.MAX_LEN - 1));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400608 int actual;
609 int expected;
610 if (pos >= state.len[i] - 1) {
611 memcpy(state.ptr1, state.ptr2, state.len[i]);
612 expected = 0;
613 actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
614 } else {
615 memcpy(state.ptr1, state.ptr2, pos);
616 if (state.ptr1[pos] > state.ptr2[pos]) {
617 expected = 1;
618 } else if (state.ptr1[pos] == state.ptr2[pos]) {
619 state.ptr1[pos + 1] = '\0';
620 state.ptr2[pos + 1] = '\0';
621 expected = 0;
622 } else {
623 expected = -1;
624 }
625 actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
626 }
627
628 ASSERT_EQ(expected, signum(actual));
629 }
630 }
631}
632
Christopher Ferris950a58e2014-04-04 14:38:18 -0700633TEST(string, stpncpy) {
634 StringTestState<char> state(SMALL);
635 for (size_t j = 0; j < ITER; j++) {
636 state.NewIteration();
637
638 // Choose a random value to fill the string, except \0 (string terminator),
639 // or \1 (guarantees it's different from anything in ptr2).
640 memset(state.ptr1, (random() % 254) + 2, state.MAX_LEN);
641 // Choose a random size for our src buffer.
642 size_t ptr1_len = random() % state.MAX_LEN;
643 state.ptr1[ptr1_len] = '\0';
644 // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
645 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
646 // Init ptr2 to a set value.
647 memset(state.ptr2, '\1', state.MAX_LEN);
648
649 // Choose a random amount of data to copy.
650 size_t copy_len = random() % state.MAX_LEN;
651
652 // Set the second half of ptr to the expected pattern in ptr2.
653 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
654 memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
655 size_t expected_end;
656 if (copy_len > ptr1_len) {
657 memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
658 expected_end = ptr1_len;
659 } else {
660 expected_end = copy_len;
661 }
662
663 ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
664
665 // Verify ptr1 was not modified.
666 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
667 // Verify ptr2 contains the expected data.
668 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
669 }
670}
671
Anna Tikhonova036154b2012-10-05 15:21:11 +0400672TEST(string, strncpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400673 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400674 for (size_t j = 0; j < ITER; j++) {
675 state.NewIteration();
676
Christopher Ferris950a58e2014-04-04 14:38:18 -0700677 // Choose a random value to fill the string, except \0 (string terminator),
678 // or \1 (guarantees it's different from anything in ptr2).
679 memset(state.ptr1, (random() % 254) + 2, state.MAX_LEN);
680 // Choose a random size for our src buffer.
681 size_t ptr1_len = random() % state.MAX_LEN;
682 state.ptr1[ptr1_len] = '\0';
683 // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
Anna Tikhonova036154b2012-10-05 15:21:11 +0400684 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700685 // Init ptr2 to a set value.
Anna Tikhonova036154b2012-10-05 15:21:11 +0400686 memset(state.ptr2, '\1', state.MAX_LEN);
687
Christopher Ferris950a58e2014-04-04 14:38:18 -0700688 // Choose a random amount of data to copy.
689 size_t copy_len = random() % state.MAX_LEN;
690
691 // Set the second half of ptr to the expected pattern in ptr2.
692 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
693 memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
694 size_t expected_end;
695 if (copy_len > ptr1_len) {
696 memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
697 expected_end = ptr1_len;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400698 } else {
Christopher Ferris950a58e2014-04-04 14:38:18 -0700699 expected_end = copy_len;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400700 }
701
Christopher Ferris950a58e2014-04-04 14:38:18 -0700702 ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400703
Christopher Ferris950a58e2014-04-04 14:38:18 -0700704 // Verify ptr1 was not modified.
705 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
706 // Verify ptr2 contains the expected data.
707 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400708 }
709}
710
711TEST(string, strrchr) {
712 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400713 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400714 for (size_t i = 1; i < state.n; i++) {
715 for (size_t j = 0; j < POS_ITER; j++) {
716 state.NewIteration();
717
718 if (~seek_char > 0) {
719 memset(state.ptr1, ~seek_char, state.len[i]);
720 } else {
721 memset(state.ptr1, '\1', state.len[i]);
722 }
723 state.ptr1[state.len[i] - 1] = '\0';
724
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700725 size_t pos = random() % state.MAX_LEN;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400726 char* expected;
727 if (pos >= state.len[i] - 1) {
728 if (seek_char == 0) {
729 expected = state.ptr1 + state.len[i] - 1;
730 } else {
731 expected = NULL;
732 }
733 } else {
734 state.ptr1[pos] = seek_char;
735 expected = state.ptr1 + pos;
736 }
737
738 ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
739 }
740 }
741}
742
743TEST(string, memchr) {
744 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400745 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400746 for (size_t i = 0; i < state.n; i++) {
747 for (size_t j = 0; j < POS_ITER; j++) {
748 state.NewIteration();
749
750 memset(state.ptr1, ~seek_char, state.len[i]);
751
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700752 size_t pos = random() % state.MAX_LEN;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400753 char* expected;
754 if (pos >= state.len[i]) {
755 expected = NULL;
756 } else {
757 state.ptr1[pos] = seek_char;
758 expected = state.ptr1 + pos;
759 }
760
761 ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
762 }
763 }
764}
765
Christopher Ferris61833de2014-07-30 16:06:56 -0700766TEST(string, memchr_zero) {
767 uint8_t* buffer;
768 ASSERT_EQ(0, posix_memalign(reinterpret_cast<void**>(&buffer), 64, 64));
769 memset(buffer, 10, 64);
770 ASSERT_TRUE(NULL == memchr(buffer, 5, 0));
771 ASSERT_TRUE(NULL == memchr(buffer, 10, 0));
772}
773
Anna Tikhonova036154b2012-10-05 15:21:11 +0400774TEST(string, memrchr) {
775 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400776 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400777 for (size_t i = 0; i < state.n; i++) {
778 for (size_t j = 0; j < POS_ITER; j++) {
779 state.NewIteration();
780
781 memset(state.ptr1, ~seek_char, state.len[i]);
782
Dmitriy Ivanov61c41472014-09-04 12:47:07 -0700783 size_t pos = random() % state.MAX_LEN;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400784 char* expected;
785 if (pos >= state.len[i]) {
786 expected = NULL;
787 } else {
788 state.ptr1[pos] = seek_char;
789 expected = state.ptr1 + pos;
790 }
791
792 ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
793 }
794 }
795}
796
797TEST(string, memcmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400798 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400799 for (size_t i = 0; i < state.n; i++) {
800 for (size_t j = 0; j < POS_ITER; j++) {
801 state.NewIteration();
802
803 int c1 = random() & 0xff;
804 int c2 = random() & 0xff;
805 memset(state.ptr1, c1, state.MAX_LEN);
806 memset(state.ptr2, c1, state.MAX_LEN);
807
808 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
809 state.ptr2[pos] = c2;
810
811 int expected = (static_cast<int>(c1) - static_cast<int>(c2));
812 int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
813
814 ASSERT_EQ(signum(expected), signum(actual));
815 }
816 }
817}
818
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400819TEST(string, wmemcmp) {
820 StringTestState<wchar_t> state(SMALL);
821
822 for (size_t i = 0; i < state.n; i++) {
823 for (size_t j = 0; j < POS_ITER; j++) {
824 state.NewIteration();
825
826 long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1;
827 int c1 = rand() & mask;
828 int c2 = rand() & mask;
829 wmemset(state.ptr1, c1, state.MAX_LEN);
830 wmemset(state.ptr2, c1, state.MAX_LEN);
831
832 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
833 state.ptr2[pos] = c2;
834
835 int expected = (static_cast<int>(c1) - static_cast<int>(c2));
836 int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
837
838 ASSERT_EQ(signum(expected), signum(actual));
839 }
840 }
841}
842
Anna Tikhonova036154b2012-10-05 15:21:11 +0400843TEST(string, memcpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400844 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400845 int rand = random() & 255;
846 for (size_t i = 0; i < state.n - 1; i++) {
847 for (size_t j = 0; j < POS_ITER; j++) {
848 state.NewIteration();
849
850 size_t pos = random() % (state.MAX_LEN - state.len[i]);
851
852 memset(state.ptr1, rand, state.len[i]);
853 memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
854
855 memset(state.ptr2, rand, state.len[i]);
856 memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
857 memset(state.ptr2 + pos, '\0', state.len[i]);
858
859 ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
860 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
861 }
862 }
863}
864
865TEST(string, memset) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400866 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400867 char ch = random () & 255;
868 for (size_t i = 0; i < state.n - 1; i++) {
869 for (size_t j = 0; j < POS_ITER; j++) {
870 state.NewIteration();
871
872 memset(state.ptr1, ~ch, state.MAX_LEN);
873 memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
874
875 size_t pos = random () % (state.MAX_LEN - state.len[i]);
876 for (size_t k = pos; k < pos + state.len[i]; k++) {
877 state.ptr1[k] = ch;
878 }
879
880 ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
881
882 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
883 }
884 }
885}
886
887TEST(string, memmove) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400888 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400889 for (size_t i = 0; i < state.n - 1; i++) {
890 for (size_t j = 0; j < POS_ITER; j++) {
891 state.NewIteration();
892
893 memset(state.ptr1, random() & 255, 2 * state.MAX_LEN);
894
895 size_t pos = random() % (state.MAX_LEN - state.len[i]);
896
897 memset(state.ptr1, random() & 255, state.len[i]);
898 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
899 memcpy(state.ptr, state.ptr1, state.len[i]);
900 memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
901
902 ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
903 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
904 }
905 }
906}
907
Varvara Rainchikfce86142014-05-27 12:41:55 +0400908TEST(string, memmove_cache_size) {
909 size_t len = 600000;
910 int max_alignment = 31;
911 int alignments[] = {0, 5, 11, 29, 30};
912 char* ptr = reinterpret_cast<char*>(malloc(sizeof(char) * len));
913 char* ptr1 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len));
914 char* glob_ptr2 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len + max_alignment));
915 size_t pos = 64;
916
917 ASSERT_TRUE(ptr != NULL);
918 ASSERT_TRUE(ptr1 != NULL);
919 ASSERT_TRUE(glob_ptr2 != NULL);
920
921 for (int i = 0; i < 5; i++) {
922 char* ptr2 = glob_ptr2 + alignments[i];
923 memset(ptr1, random() & 255, 2 * len);
924 memset(ptr1, random() & 255, len);
925 memcpy(ptr2, ptr1, 2 * len);
926 memcpy(ptr, ptr1, len);
927 memcpy(ptr1 + pos, ptr, len);
928
929 ASSERT_TRUE(memmove(ptr2 + pos, ptr, len) == ptr2 + pos);
930 ASSERT_EQ(0, memcmp(ptr2, ptr1, 2 * len));
931 }
932 free(ptr);
933 free(ptr1);
934 free(glob_ptr2);
935}
936
Shu Zhang6c80ccd2014-05-12 18:12:15 +0800937static void verify_memmove(char* src_copy, char* dst, char* src, size_t size) {
938 memset(dst, 0, size);
939 memcpy(src, src_copy, size);
940 ASSERT_EQ(dst, memmove(dst, src, size));
941 ASSERT_EQ(0, memcmp(dst, src_copy, size));
942}
943
944#define MEMMOVE_DATA_SIZE (1024*1024*3)
945
946TEST(string, memmove_check) {
947 char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
948 ASSERT_TRUE(buffer != NULL);
949
950 char* src_data = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
951 ASSERT_TRUE(src_data != NULL);
952 // Initialize to a known pattern to copy into src for each test and
953 // to compare dst against.
954 for (size_t i = 0; i < MEMMOVE_DATA_SIZE; i++) {
955 src_data[i] = (i + 1) % 255;
956 }
957
958 // Check all different dst offsets between 0 and 127 inclusive.
959 char* src = buffer;
960 for (size_t i = 0; i < 127; i++) {
961 char* dst = buffer + 256 + i;
962 // Small copy.
963 verify_memmove(src_data, dst, src, 1024);
964
965 // Medium copy.
966 verify_memmove(src_data, dst, src, 64 * 1024);
967
968 // Medium copy.
969 verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
970 }
971
972 // Check all leftover size offsets between 1 and 127 inclusive.
973 char* dst = buffer + 256;
974 src = buffer;
975 for (size_t size = 1; size < 127; size++) {
976 // Small copy.
977 verify_memmove(src_data, dst, src, 1024);
978
979 // Medium copy.
980 verify_memmove(src_data, dst, src, 64 * 1024);
981
982 // Large copy.
983 verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
984 }
985}
986
Anna Tikhonova036154b2012-10-05 15:21:11 +0400987TEST(string, bcopy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400988 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400989 for (size_t i = 0; i < state.n; i++) {
990 for (size_t j = 0; j < POS_ITER; j++) {
991 state.NewIteration();
992
993 memset(state.ptr1, random() & 255, state.MAX_LEN);
994 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN);
995 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
996
997 size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
998 memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
999
1000 bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
1001 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
1002 }
1003 }
1004}
1005
1006TEST(string, bzero) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +04001007 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +04001008 for (size_t j = 0; j < ITER; j++) {
1009 state.NewIteration();
1010
1011 memset(state.ptr1, random() & 255, state.MAX_LEN);
1012
1013 size_t start = random() % state.MAX_LEN;
1014 size_t end = start + random() % (state.MAX_LEN - start);
1015
1016 memcpy(state.ptr2, state.ptr1, start);
1017 memset(state.ptr2 + start, '\0', end - start);
1018 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
1019
1020 bzero(state.ptr1 + start, end - start);
1021
1022 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
1023 }
1024}
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001025
1026static void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1027 memset(src, (len % 255) + 1, len);
1028 memset(dst, 0, len);
1029
1030 ASSERT_EQ(dst, memcpy(dst, src, len));
1031 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1032}
1033
1034TEST(string, memcpy_align) {
1035 RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
1036}
1037
1038TEST(string, memcpy_overread) {
1039 RunSrcDstBufferOverreadTest(DoMemcpyTest);
1040}
1041
Shu Zhang6c80ccd2014-05-12 18:12:15 +08001042static void DoMemmoveTest(uint8_t* src, uint8_t* dst, size_t len) {
1043 memset(src, (len % 255) + 1, len);
1044 memset(dst, 0, len);
1045
1046 ASSERT_EQ(dst, memmove(dst, src, len));
1047 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1048}
1049
1050TEST(string, memmove_align) {
1051 RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
1052}
1053
1054TEST(string, memmove_overread) {
1055 RunSrcDstBufferOverreadTest(DoMemmoveTest);
1056}
1057
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001058static void DoMemsetTest(uint8_t* buf, size_t len) {
1059 for (size_t i = 0; i < len; i++) {
1060 buf[i] = 0;
1061 }
1062 int value = (len % 255) + 1;
1063 ASSERT_EQ(buf, memset(buf, value, len));
1064 for (size_t i = 0; i < len; i++) {
1065 ASSERT_EQ(value, buf[i]);
1066 }
1067}
1068
1069TEST(string, memset_align) {
1070 RunSingleBufferAlignTest(LARGE, DoMemsetTest);
1071}
1072
1073static void DoStrlenTest(uint8_t* buf, size_t len) {
1074 if (len >= 1) {
1075 memset(buf, (32 + (len % 96)), len - 1);
1076 buf[len-1] = '\0';
1077 ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf)));
1078 }
1079}
1080
1081TEST(string, strlen_align) {
1082 RunSingleBufferAlignTest(LARGE, DoStrlenTest);
1083}
1084
1085TEST(string, strlen_overread) {
1086 RunSingleBufferOverreadTest(DoStrlenTest);
1087}
1088
1089static void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1090 if (len >= 1) {
1091 memset(src, (32 + (len % 96)), len - 1);
1092 src[len-1] = '\0';
1093 memset(dst, 0, len);
1094 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst),
1095 reinterpret_cast<char*>(src))));
1096 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1097 }
1098}
1099
1100TEST(string, strcpy_align) {
1101 RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
1102}
1103
1104TEST(string, strcpy_overread) {
1105 RunSrcDstBufferOverreadTest(DoStrcpyTest);
1106}
1107
Christopher Ferris950a58e2014-04-04 14:38:18 -07001108static void DoStpcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1109 if (len >= 1) {
1110 memset(src, (32 + (len % 96)), len - 1);
1111 src[len-1] = '\0';
1112 memset(dst, 0, len);
1113 ASSERT_EQ(dst+len-1, reinterpret_cast<uint8_t*>(stpcpy(reinterpret_cast<char*>(dst),
1114 reinterpret_cast<char*>(src))));
1115 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1116 }
1117}
1118
1119TEST(string, stpcpy_align) {
1120 RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest);
1121}
1122
1123TEST(string, stpcpy_overread) {
1124 RunSrcDstBufferOverreadTest(DoStpcpyTest);
1125}
1126
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001127// Use our own incrementer to cut down on the total number of calls.
Christopher Ferrise5bbb6b2013-12-03 18:39:10 -08001128static size_t LargeSetIncrement(size_t len) {
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001129 if (len >= 4096) {
1130 return 4096;
1131 } else if (len >= 1024) {
1132 return 1024;
1133 } else if (len >= 256) {
1134 return 256;
1135 }
1136 return 1;
1137}
1138
1139#define STRCAT_DST_LEN 128
1140
1141static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) {
1142 if (len >= 1) {
1143 int value = 32 + (len % 96);
1144 memset(src, value, len - 1);
1145 src[len-1] = '\0';
1146
1147 if (len >= STRCAT_DST_LEN) {
1148 // Create a small buffer for doing quick compares in each loop.
1149 uint8_t cmp_buf[STRCAT_DST_LEN];
1150 // Make sure dst string contains a different value then the src string.
1151 int value2 = 32 + (value + 2) % 96;
1152 memset(cmp_buf, value2, sizeof(cmp_buf));
1153
1154 for (size_t i = 1; i <= STRCAT_DST_LEN; i++) {
1155 memset(dst, value2, i-1);
1156 memset(dst+i-1, 0, len-i);
1157 src[len-i] = '\0';
1158 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
1159 reinterpret_cast<char*>(src))));
1160 ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
1161 ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
1162 }
1163 } else {
1164 dst[0] = '\0';
1165 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
1166 reinterpret_cast<char*>(src))));
1167 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1168 }
1169 }
1170}
1171
1172TEST(string, strcat_align) {
Christopher Ferrise5bbb6b2013-12-03 18:39:10 -08001173 RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement);
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001174}
1175
1176TEST(string, strcat_overread) {
1177 RunSrcDstBufferOverreadTest(DoStrcatTest);
1178}
Christopher Ferrise5bbb6b2013-12-03 18:39:10 -08001179
1180static void DoStrcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
1181 if (len >= 1) {
1182 memset(buf1, (32 + (len % 96)), len - 1);
1183 buf1[len-1] = '\0';
1184 memset(buf2, (32 + (len % 96)), len - 1);
1185 buf2[len-1] = '\0';
1186 ASSERT_EQ(0, strcmp(reinterpret_cast<char*>(buf1),
1187 reinterpret_cast<char*>(buf2)));
1188 }
1189}
1190
1191static void DoStrcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
1192 // Do string length differences.
1193 int c = (32 + (len1 % 96));
1194 memset(buf1, c, len1 - 1);
1195 buf1[len1-1] = '\0';
1196 memset(buf2, c, len2 - 1);
1197 buf2[len2-1] = '\0';
1198 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1199 reinterpret_cast<char*>(buf2)));
1200
1201 // Do single character differences.
1202 size_t len;
1203 if (len1 > len2) {
1204 len = len2;
1205 } else {
1206 len = len1;
1207 }
1208 // Need at least a two character buffer to do this test.
1209 if (len > 1) {
1210 buf1[len-1] = '\0';
1211 buf2[len-1] = '\0';
1212 int diff_c = (c + 1) % 96;
1213
1214 buf1[len-2] = diff_c;
1215 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1216 reinterpret_cast<char*>(buf2)));
1217
1218 buf1[len-2] = c;
1219 buf2[len-2] = diff_c;
1220 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1221 reinterpret_cast<char*>(buf2)));
1222 }
1223}
1224
1225TEST(string, strcmp_align) {
1226 RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement);
1227}
1228
1229TEST(string, strcmp_overread) {
1230 RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest);
1231}
1232
1233static void DoMemcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
1234 memset(buf1, len+1, len);
1235 memset(buf2, len+1, len);
1236 ASSERT_EQ(0, memcmp(buf1, buf2, len));
1237}
1238
1239static void DoMemcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
1240 size_t len;
1241 if (len1 > len2) {
1242 len = len2;
1243 } else {
1244 len = len1;
1245 }
1246
1247 memset(buf1, len2+1, len);
1248 buf1[len-1] = len2;
1249 memset(buf2, len2+1, len);
1250 ASSERT_NE(0, memcmp(buf1, buf2, len));
1251
1252 buf1[len-1] = len2+1;
1253 buf2[len-1] = len2;
1254 ASSERT_NE(0, memcmp(buf1, buf2, len));
1255}
1256
1257TEST(string, memcmp_align) {
1258 RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement);
1259}
1260
1261TEST(string, memcmp_overread) {
1262 RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
1263}
Christopher Ferris3a657d02014-06-27 12:33:22 -07001264
1265static void DoStrchrTest(uint8_t* buf, size_t len) {
1266 if (len >= 1) {
1267 char value = 32 + (len % 96);
1268 char search_value = 33 + (len % 96);
1269 memset(buf, value, len - 1);
1270 buf[len-1] = '\0';
1271 ASSERT_EQ(NULL, strchr(reinterpret_cast<char*>(buf), search_value));
1272 ASSERT_EQ(reinterpret_cast<char*>(&buf[len-1]), strchr(reinterpret_cast<char*>(buf), '\0'));
1273 if (len >= 2) {
1274 buf[0] = search_value;
1275 ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strchr(reinterpret_cast<char*>(buf), search_value));
1276 buf[0] = value;
1277 buf[len-2] = search_value;
1278 ASSERT_EQ(reinterpret_cast<char*>(&buf[len-2]), strchr(reinterpret_cast<char*>(buf), search_value));
1279 }
1280 }
1281}
1282
1283TEST(string, strchr_align) {
1284 RunSingleBufferAlignTest(MEDIUM, DoStrchrTest);
1285}
1286
1287TEST(string, strchr_overread) {
1288 RunSingleBufferOverreadTest(DoStrchrTest);
1289}