blob: 7db8e21403ef34ba7f69badbe3080565d62e9b5b [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
Elliott Hughes416d7dd2014-08-18 17:28:32 -070017#define _GNU_SOURCE 1
18
Elliott Hughes09c39d62014-08-19 14:30:30 -070019#include <string.h>
Irina Tirdeab5f053b2012-09-08 09:17:54 +030020
21#include <errno.h>
Elliott Hughes09c39d62014-08-19 14:30:30 -070022#include <gtest/gtest.h>
Dan Alberte5fdaa42014-06-14 01:04:31 +000023#include <malloc.h>
Anna Tikhonova036154b2012-10-05 15:21:11 +040024#include <math.h>
Irina Tirdeab5f053b2012-09-08 09:17:54 +030025
Christopher Ferrisb687ad32013-11-06 17:32:11 -080026#include "buffer_tests.h"
27
Anna Tikhonova036154b2012-10-05 15:21:11 +040028#define KB 1024
29#define SMALL 1*KB
Christopher Ferrisb687ad32013-11-06 17:32:11 -080030#define MEDIUM 4*KB
Anna Tikhonova036154b2012-10-05 15:21:11 +040031#define LARGE 64*KB
32
33static int signum(int i) {
34 if (i < 0) {
35 return -1;
36 } else if (i > 0) {
37 return 1;
38 }
39 return 0;
40}
41
Irina Tirdeab5f053b2012-09-08 09:17:54 +030042TEST(string, strerror) {
43 // Valid.
44 ASSERT_STREQ("Success", strerror(0));
45 ASSERT_STREQ("Operation not permitted", strerror(1));
46
47 // Invalid.
Elliott Hughese6e60062013-01-10 16:01:59 -080048 ASSERT_STREQ("Unknown error -1", strerror(-1));
Irina Tirdeab5f053b2012-09-08 09:17:54 +030049 ASSERT_STREQ("Unknown error 1234", strerror(1234));
50}
51
Christopher Ferrisf04935c2013-12-20 18:43:21 -080052#if defined(__BIONIC__)
Elliott Hughesad88a082012-10-24 18:37:21 -070053static void* ConcurrentStrErrorFn(void*) {
Irina Tirdeab5f053b2012-09-08 09:17:54 +030054 bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
55 return reinterpret_cast<void*>(equal);
56}
Christopher Ferrisf04935c2013-12-20 18:43:21 -080057#endif // __BIONIC__
Irina Tirdeab5f053b2012-09-08 09:17:54 +030058
Christopher Ferrisf04935c2013-12-20 18:43:21 -080059// glibc's strerror isn't thread safe, only its strsignal.
Irina Tirdeab5f053b2012-09-08 09:17:54 +030060TEST(string, strerror_concurrent) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -080061#if defined(__BIONIC__)
Irina Tirdeab5f053b2012-09-08 09:17:54 +030062 const char* strerror1001 = strerror(1001);
63 ASSERT_STREQ("Unknown error 1001", strerror1001);
64
65 pthread_t t;
66 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL));
67 void* result;
68 ASSERT_EQ(0, pthread_join(t, &result));
69 ASSERT_TRUE(static_cast<bool>(result));
70
71 ASSERT_STREQ("Unknown error 1001", strerror1001);
Christopher Ferrisf04935c2013-12-20 18:43:21 -080072#else // __BIONIC__
73 GTEST_LOG_(INFO) << "This test does nothing.\n";
74#endif // __BIONIC__
Irina Tirdeab5f053b2012-09-08 09:17:54 +030075}
Elliott Hughesad88a082012-10-24 18:37:21 -070076
Elliott Hughes416d7dd2014-08-18 17:28:32 -070077TEST(string, gnu_strerror_r) {
Irina Tirdeab5f053b2012-09-08 09:17:54 +030078 char buf[256];
79
Elliott Hughes416d7dd2014-08-18 17:28:32 -070080 // Note that glibc doesn't necessarily write into the buffer.
81
Irina Tirdeab5f053b2012-09-08 09:17:54 +030082 // Valid.
Elliott Hughes416d7dd2014-08-18 17:28:32 -070083 ASSERT_STREQ("Success", strerror_r(0, buf, sizeof(buf)));
84#if defined(__BIONIC__)
Irina Tirdeab5f053b2012-09-08 09:17:54 +030085 ASSERT_STREQ("Success", buf);
Elliott Hughes416d7dd2014-08-18 17:28:32 -070086#endif
87 ASSERT_STREQ("Operation not permitted", strerror_r(1, buf, sizeof(buf)));
88#if defined(__BIONIC__)
Irina Tirdeab5f053b2012-09-08 09:17:54 +030089 ASSERT_STREQ("Operation not permitted", buf);
Elliott Hughes416d7dd2014-08-18 17:28:32 -070090#endif
Irina Tirdeab5f053b2012-09-08 09:17:54 +030091
92 // Invalid.
Elliott Hughes416d7dd2014-08-18 17:28:32 -070093 ASSERT_STREQ("Unknown error -1", strerror_r(-1, buf, sizeof(buf)));
Nick Kralevich60605892013-01-15 10:35:09 -080094 ASSERT_STREQ("Unknown error -1", buf);
Elliott Hughes416d7dd2014-08-18 17:28:32 -070095 ASSERT_STREQ("Unknown error 1234", strerror_r(1234, buf, sizeof(buf)));
Irina Tirdeab5f053b2012-09-08 09:17:54 +030096 ASSERT_STREQ("Unknown error 1234", buf);
97
98 // Buffer too small.
Elliott Hughes416d7dd2014-08-18 17:28:32 -070099 errno = 0;
100 memset(buf, 0, sizeof(buf));
101 ASSERT_EQ(buf, strerror_r(4567, buf, 2));
102 ASSERT_STREQ("U", buf);
103 // The GNU strerror_r doesn't set errno (the POSIX one sets it to ERANGE).
104 ASSERT_EQ(0, errno);
Irina Tirdeab5f053b2012-09-08 09:17:54 +0300105}
Irina Tirdeab5f053b2012-09-08 09:17:54 +0300106
107TEST(string, strsignal) {
108 // A regular signal.
109 ASSERT_STREQ("Hangup", strsignal(1));
110
111 // A real-time signal.
Elliott Hughes0990d4f2014-04-30 09:45:40 -0700112 ASSERT_STREQ("Real-time signal 14", strsignal(SIGRTMIN + 14));
113 // One of the signals the C library keeps to itself.
114 ASSERT_STREQ("Unknown signal 32", strsignal(__SIGRTMIN));
Irina Tirdeab5f053b2012-09-08 09:17:54 +0300115
116 // Errors.
117 ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
118 ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small.
119 ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large.
120}
121
Elliott Hughesad88a082012-10-24 18:37:21 -0700122static void* ConcurrentStrSignalFn(void*) {
Irina Tirdeab5f053b2012-09-08 09:17:54 +0300123 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
124 return reinterpret_cast<void*>(equal);
125}
126
127TEST(string, strsignal_concurrent) {
128 const char* strsignal1001 = strsignal(1001);
129 ASSERT_STREQ("Unknown signal 1001", strsignal1001);
130
131 pthread_t t;
132 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL));
133 void* result;
134 ASSERT_EQ(0, pthread_join(t, &result));
135 ASSERT_TRUE(static_cast<bool>(result));
136
137 ASSERT_STREQ("Unknown signal 1001", strsignal1001);
138}
Anna Tikhonova036154b2012-10-05 15:21:11 +0400139
140// TODO: where did these numbers come from?
141#define POS_ITER 10
142#define ITER 500
143
144// For every length we want to test, vary and change alignment
145// of allocated memory, fill it with some values, calculate
146// expected result and then run function and compare what we got.
147// These tests contributed by Intel Corporation.
148// TODO: make these tests more intention-revealing and less random.
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400149template<class Character>
Anna Tikhonova036154b2012-10-05 15:21:11 +0400150struct StringTestState {
151 StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) {
152 int max_alignment = 64;
153
154 // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
Dan Alberte5fdaa42014-06-14 01:04:31 +0000155 glob_ptr = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
156 glob_ptr1 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
157 glob_ptr2 = reinterpret_cast<Character*>(memalign(sysconf(_SC_PAGESIZE), 2 * sizeof(Character) * MAX_LEN + max_alignment));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400158
159 InitLenArray();
160
161 srandom(1234);
162 }
163
164 ~StringTestState() {
165 free(glob_ptr);
166 free(glob_ptr1);
167 free(glob_ptr2);
168 }
169
170 void NewIteration() {
171 int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 };
172 int usable_alignments = 10;
173 int align1 = alignments[random() % (usable_alignments - 1)];
174 int align2 = alignments[random() % (usable_alignments - 1)];
175
176 ptr = glob_ptr + align1;
177 ptr1 = glob_ptr1 + align1;
178 ptr2 = glob_ptr2 + align2;
179 }
180
181 const size_t MAX_LEN;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400182 Character *ptr, *ptr1, *ptr2;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400183 size_t n;
184 int len[ITER + 1];
185
186 private:
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400187 Character *glob_ptr, *glob_ptr1, *glob_ptr2;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400188
189 // Calculate input lengths and fill state.len with them.
190 // Test small lengths with more density than big ones. Manually push
191 // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
192 // Return number of lengths to test.
193 void InitLenArray() {
194 n = 0;
195 len[n++] = 0;
196 for (size_t i = 1; i < ITER; ++i) {
197 int l = (int) exp(log((double) MAX_LEN) * i / ITER);
198 if (l != len[n - 1]) {
199 len[n++] = l;
200 }
201 }
202 len[n++] = MAX_LEN;
203 }
204};
205
206TEST(string, strcat) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400207 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400208 for (size_t i = 1; i < state.n; i++) {
209 for (size_t j = 0; j < POS_ITER; j++) {
210 state.NewIteration();
211
212 memset(state.ptr2, '\2', state.MAX_LEN);
213 state.ptr2[state.MAX_LEN - 1] = '\0';
214 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
215
216 memset(state.ptr1, random() & 255, state.len[i]);
217 state.ptr1[random() % state.len[i]] = '\0';
218 state.ptr1[state.len[i] - 1] = '\0';
219
220 strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
221
222 EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
223 EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
224 }
225 }
226}
227
Nick Kralevich13476de2013-06-03 10:58:06 -0700228// one byte target with "\0" source
229TEST(string, strcpy2) {
230 char buf[1];
231 char* orig = strdup("");
Christopher Ferris950a58e2014-04-04 14:38:18 -0700232 ASSERT_EQ(buf, strcpy(buf, orig));
Nick Kralevich13476de2013-06-03 10:58:06 -0700233 ASSERT_EQ('\0', buf[0]);
234 free(orig);
235}
236
237// multibyte target where we under fill target
238TEST(string, strcpy3) {
239 char buf[10];
240 char* orig = strdup("12345");
241 memset(buf, 'A', sizeof(buf));
Christopher Ferris950a58e2014-04-04 14:38:18 -0700242 ASSERT_EQ(buf, strcpy(buf, orig));
243 ASSERT_STREQ("12345", buf);
Nick Kralevich13476de2013-06-03 10:58:06 -0700244 ASSERT_EQ('A', buf[6]);
245 ASSERT_EQ('A', buf[7]);
246 ASSERT_EQ('A', buf[8]);
247 ASSERT_EQ('A', buf[9]);
248 free(orig);
249}
250
251// multibyte target where we fill target exactly
252TEST(string, strcpy4) {
253 char buf[10];
254 char* orig = strdup("123456789");
255 memset(buf, 'A', sizeof(buf));
Christopher Ferris950a58e2014-04-04 14:38:18 -0700256 ASSERT_EQ(buf, strcpy(buf, orig));
257 ASSERT_STREQ("123456789", buf);
258 free(orig);
259}
260
261// one byte target with "\0" source
262TEST(string, stpcpy2) {
263 char buf[1];
264 char* orig = strdup("");
265 ASSERT_EQ(buf, stpcpy(buf, orig));
266 ASSERT_EQ('\0', buf[0]);
267 free(orig);
268}
269
270// multibyte target where we under fill target
271TEST(string, stpcpy3) {
272 char buf[10];
273 char* orig = strdup("12345");
274 memset(buf, 'A', sizeof(buf));
275 ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
276 ASSERT_STREQ("12345", buf);
277 ASSERT_EQ('A', buf[6]);
278 ASSERT_EQ('A', buf[7]);
279 ASSERT_EQ('A', buf[8]);
280 ASSERT_EQ('A', buf[9]);
281 free(orig);
282}
283
284// multibyte target where we fill target exactly
285TEST(string, stpcpy4) {
286 char buf[10];
287 char* orig = strdup("123456789");
288 memset(buf, 'A', sizeof(buf));
289 ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
290 ASSERT_STREQ("123456789", buf);
Nick Kralevich13476de2013-06-03 10:58:06 -0700291 free(orig);
292}
293
Nick Kralevichcf870192013-05-30 16:48:53 -0700294TEST(string, strcat2) {
295 char buf[10];
296 memset(buf, 'A', sizeof(buf));
297 buf[0] = 'a';
298 buf[1] = '\0';
299 char* res = strcat(buf, "01234");
300 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700301 ASSERT_STREQ("a01234", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700302 ASSERT_EQ('A', buf[7]);
303 ASSERT_EQ('A', buf[8]);
304 ASSERT_EQ('A', buf[9]);
305}
306
307TEST(string, strcat3) {
308 char buf[10];
309 memset(buf, 'A', sizeof(buf));
310 buf[0] = 'a';
311 buf[1] = '\0';
312 char* res = strcat(buf, "01234567");
313 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700314 ASSERT_STREQ("a01234567", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700315}
316
317TEST(string, strncat2) {
318 char buf[10];
319 memset(buf, 'A', sizeof(buf));
320 buf[0] = 'a';
321 buf[1] = '\0';
322 char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1);
323 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700324 ASSERT_STREQ("a01234", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700325 ASSERT_EQ('A', buf[7]);
326 ASSERT_EQ('A', buf[8]);
327 ASSERT_EQ('A', buf[9]);
328}
329
330TEST(string, strncat3) {
331 char buf[10];
332 memset(buf, 'A', sizeof(buf));
333 buf[0] = 'a';
334 buf[1] = '\0';
335 char* res = strncat(buf, "0123456789", 5);
336 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700337 ASSERT_STREQ("a01234", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700338 ASSERT_EQ('A', buf[7]);
339 ASSERT_EQ('A', buf[8]);
340 ASSERT_EQ('A', buf[9]);
341}
342
343TEST(string, strncat4) {
344 char buf[10];
345 memset(buf, 'A', sizeof(buf));
346 buf[0] = 'a';
347 buf[1] = '\0';
348 char* res = strncat(buf, "01234567", 8);
349 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700350 ASSERT_STREQ("a01234567", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700351}
352
353TEST(string, strncat5) {
354 char buf[10];
355 memset(buf, 'A', sizeof(buf));
356 buf[0] = 'a';
357 buf[1] = '\0';
358 char* res = strncat(buf, "01234567", 9);
359 ASSERT_EQ(buf, res);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700360 ASSERT_STREQ("a01234567", buf);
Nick Kralevichcf870192013-05-30 16:48:53 -0700361}
362
Nick Kralevich4f40e512013-04-19 16:54:22 -0700363TEST(string, strchr_with_0) {
364 char buf[10];
365 const char* s = "01234";
366 memcpy(buf, s, strlen(s) + 1);
367 EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
368}
369
Christopher Ferris3a657d02014-06-27 12:33:22 -0700370TEST(string, strchr_multiple) {
371 char str[128];
372 memset(str, 'a', sizeof(str) - 1);
373 str[sizeof(str)-1] = '\0';
374
375 // Verify that strchr finds the first occurrence of 'a' in a string
376 // filled with 'a' characters. Iterate over the string putting
377 // non 'a' characters at the front of the string during each iteration
378 // and continue to verify that strchr can find the first occurrence
379 // properly. The idea is to cover all possible alignments of the location
380 // of the first occurrence of the 'a' character and which includes
381 // other 'a' characters close by.
382 for (size_t i = 0; i < sizeof(str) - 1; i++) {
383 EXPECT_EQ(&str[i], strchr(str, 'a'));
384 str[i] = 'b';
385 }
386}
387
Anna Tikhonova036154b2012-10-05 15:21:11 +0400388TEST(string, strchr) {
389 int seek_char = random() & 255;
390
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400391 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400392 for (size_t i = 1; i < state.n; i++) {
393 for (size_t j = 0; j < POS_ITER; j++) {
394 state.NewIteration();
395
396 if (~seek_char > 0) {
397 memset(state.ptr1, ~seek_char, state.len[i]);
398 } else {
399 memset(state.ptr1, '\1', state.len[i]);
400 }
401 state.ptr1[state.len[i] - 1] = '\0';
402
403 int pos = random() % state.MAX_LEN;
404 char* expected;
405 if (pos >= state.len[i] - 1) {
406 if (seek_char == 0) {
407 expected = state.ptr1 + state.len[i] - 1;
408 } else {
409 expected = NULL;
410 }
411 } else {
412 state.ptr1[pos] = seek_char;
413 expected = state.ptr1 + pos;
414 }
415
416 ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
417 }
418 }
419}
420
421TEST(string, strcmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400422 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400423 for (size_t i = 1; i < state.n; i++) {
424 for (size_t j = 0; j < POS_ITER; j++) {
425 state.NewIteration();
426
427 memset(state.ptr1, 'v', state.MAX_LEN);
428 memset(state.ptr2, 'n', state.MAX_LEN);
429 state.ptr1[state.len[i] - 1] = '\0';
430 state.ptr2[state.len[i] - 1] = '\0';
431
432 int pos = 1 + (random() % (state.MAX_LEN - 1));
433 int actual;
434 int expected;
435 if (pos >= state.len[i] - 1) {
436 memcpy(state.ptr1, state.ptr2, state.len[i]);
437 expected = 0;
438 actual = strcmp(state.ptr1, state.ptr2);
439 } else {
440 memcpy(state.ptr1, state.ptr2, pos);
441 if (state.ptr1[pos] > state.ptr2[pos]) {
442 expected = 1;
443 } else if (state.ptr1[pos] == state.ptr2[pos]) {
444 state.ptr1[pos + 1] = '\0';
445 state.ptr2[pos + 1] = '\0';
446 expected = 0;
447 } else {
448 expected = -1;
449 }
450 actual = strcmp(state.ptr1, state.ptr2);
451 }
452
453 ASSERT_EQ(expected, signum(actual));
454 }
455 }
456}
457
Christopher Ferris950a58e2014-04-04 14:38:18 -0700458TEST(string, stpcpy) {
459 StringTestState<char> state(SMALL);
460 for (size_t j = 0; j < POS_ITER; j++) {
461 state.NewIteration();
462
463 size_t pos = random() % state.MAX_LEN;
464
465 memset(state.ptr1, '\2', pos);
466 state.ptr1[pos] = '\0';
467 state.ptr1[state.MAX_LEN - 1] = '\0';
468
469 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
470
471 memset(state.ptr2, '\1', state.MAX_LEN);
472 state.ptr2[state.MAX_LEN - 1] = '\0';
473
474 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
475 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
476 state.ptr[2 * state.MAX_LEN - 1] = '\0';
477
478 ASSERT_TRUE(stpcpy(state.ptr2, state.ptr1) == state.ptr2 + strlen(state.ptr1));
479 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
480 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
481 }
482}
483
Anna Tikhonova036154b2012-10-05 15:21:11 +0400484TEST(string, strcpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400485 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400486 for (size_t j = 0; j < POS_ITER; j++) {
487 state.NewIteration();
488
489 size_t pos = random() % state.MAX_LEN;
490
491 memset(state.ptr1, '\2', pos);
492 state.ptr1[pos] = '\0';
493 state.ptr1[state.MAX_LEN - 1] = '\0';
494
495 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
496
497 memset(state.ptr2, '\1', state.MAX_LEN);
498 state.ptr2[state.MAX_LEN - 1] = '\0';
499
500 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
501 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
502 state.ptr[2 * state.MAX_LEN - 1] = '\0';
503
504 ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
505 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
506 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
507 }
508}
509
Anna Tikhonova036154b2012-10-05 15:21:11 +0400510TEST(string, strlcat) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800511#if defined(__BIONIC__)
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400512 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400513 for (size_t i = 0; i < state.n; i++) {
514 for (size_t j = 0; j < POS_ITER; j++) {
515 state.NewIteration();
516
517 memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
518 state.ptr2[state.MAX_LEN - 1] = '\0';
519 memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
520
521 int pos = random() % state.MAX_LEN;
522 memset(state.ptr1, '\3', pos);
523 state.ptr1[pos] = '\0';
524 if (pos < state.len[i]) {
525 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
526 } else {
527 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
528 state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
529 }
530
531 strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
532
533 ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
534 }
535 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800536#else // __BIONIC__
537 GTEST_LOG_(INFO) << "This test does nothing.\n";
538#endif // __BIONIC__
Anna Tikhonova036154b2012-10-05 15:21:11 +0400539}
Anna Tikhonova036154b2012-10-05 15:21:11 +0400540
Anna Tikhonova036154b2012-10-05 15:21:11 +0400541TEST(string, strlcpy) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800542#if defined(__BIONIC__)
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400543 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400544 for (size_t j = 0; j < POS_ITER; j++) {
545 state.NewIteration();
546
547 int rand = random() & 255;
548 if (rand < 1) {
549 rand = 1;
550 }
551 memset(state.ptr1, rand, state.MAX_LEN);
552
553 size_t pos = random() % state.MAX_LEN;
554 if (pos < state.MAX_LEN) {
555 state.ptr1[pos] = '\0';
556 }
557 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
558
559 memset(state.ptr2, random() & 255, state.MAX_LEN);
560 memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
561
562 if (pos > state.MAX_LEN - 1) {
563 memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
564 state.ptr[2 * state.MAX_LEN - 1] = '\0';
565 } else {
566 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
567 }
568
569 ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
570 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
571 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
572 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800573#else // __BIONIC__
574 GTEST_LOG_(INFO) << "This test does nothing.\n";
575#endif // __BIONIC__
Anna Tikhonova036154b2012-10-05 15:21:11 +0400576}
Anna Tikhonova036154b2012-10-05 15:21:11 +0400577
578TEST(string, strncat) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400579 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400580 for (size_t i = 1; i < state.n; i++) {
581 for (size_t j = 0; j < POS_ITER; j++) {
582 state.NewIteration();
583
584 memset(state.ptr2, '\2', state.MAX_LEN);
585 state.ptr2[state.MAX_LEN - 1] = '\0';
586 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
587
588 memset(state.ptr1, random() & 255, state.len[i]);
589 state.ptr1[random() % state.len[i]] = '\0';
590 state.ptr1[state.len[i] - 1] = '\0';
591
592 size_t pos = strlen(state.ptr1);
593
594 size_t actual = random() % state.len[i];
595 strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
596 state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
597
598 ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
599 ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
600 }
601 }
602}
603
604TEST(string, strncmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400605 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400606 for (size_t i = 1; i < state.n; i++) {
607 for (size_t j = 0; j < POS_ITER; j++) {
608 state.NewIteration();
609
610 memset(state.ptr1, 'v', state.MAX_LEN);
611 memset(state.ptr2, 'n', state.MAX_LEN);
612 state.ptr1[state.len[i] - 1] = '\0';
613 state.ptr2[state.len[i] - 1] = '\0';
614
615 int pos = 1 + (random() % (state.MAX_LEN - 1));
616 int actual;
617 int expected;
618 if (pos >= state.len[i] - 1) {
619 memcpy(state.ptr1, state.ptr2, state.len[i]);
620 expected = 0;
621 actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
622 } else {
623 memcpy(state.ptr1, state.ptr2, pos);
624 if (state.ptr1[pos] > state.ptr2[pos]) {
625 expected = 1;
626 } else if (state.ptr1[pos] == state.ptr2[pos]) {
627 state.ptr1[pos + 1] = '\0';
628 state.ptr2[pos + 1] = '\0';
629 expected = 0;
630 } else {
631 expected = -1;
632 }
633 actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
634 }
635
636 ASSERT_EQ(expected, signum(actual));
637 }
638 }
639}
640
Christopher Ferris950a58e2014-04-04 14:38:18 -0700641TEST(string, stpncpy) {
642 StringTestState<char> state(SMALL);
643 for (size_t j = 0; j < ITER; j++) {
644 state.NewIteration();
645
646 // Choose a random value to fill the string, except \0 (string terminator),
647 // or \1 (guarantees it's different from anything in ptr2).
648 memset(state.ptr1, (random() % 254) + 2, state.MAX_LEN);
649 // Choose a random size for our src buffer.
650 size_t ptr1_len = random() % state.MAX_LEN;
651 state.ptr1[ptr1_len] = '\0';
652 // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
653 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
654 // Init ptr2 to a set value.
655 memset(state.ptr2, '\1', state.MAX_LEN);
656
657 // Choose a random amount of data to copy.
658 size_t copy_len = random() % state.MAX_LEN;
659
660 // Set the second half of ptr to the expected pattern in ptr2.
661 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
662 memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
663 size_t expected_end;
664 if (copy_len > ptr1_len) {
665 memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
666 expected_end = ptr1_len;
667 } else {
668 expected_end = copy_len;
669 }
670
671 ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
672
673 // Verify ptr1 was not modified.
674 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
675 // Verify ptr2 contains the expected data.
676 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
677 }
678}
679
Anna Tikhonova036154b2012-10-05 15:21:11 +0400680TEST(string, strncpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400681 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400682 for (size_t j = 0; j < ITER; j++) {
683 state.NewIteration();
684
Christopher Ferris950a58e2014-04-04 14:38:18 -0700685 // Choose a random value to fill the string, except \0 (string terminator),
686 // or \1 (guarantees it's different from anything in ptr2).
687 memset(state.ptr1, (random() % 254) + 2, state.MAX_LEN);
688 // Choose a random size for our src buffer.
689 size_t ptr1_len = random() % state.MAX_LEN;
690 state.ptr1[ptr1_len] = '\0';
691 // Copy ptr1 into ptr, used to verify that ptr1 does not get modified.
Anna Tikhonova036154b2012-10-05 15:21:11 +0400692 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
Christopher Ferris950a58e2014-04-04 14:38:18 -0700693 // Init ptr2 to a set value.
Anna Tikhonova036154b2012-10-05 15:21:11 +0400694 memset(state.ptr2, '\1', state.MAX_LEN);
695
Christopher Ferris950a58e2014-04-04 14:38:18 -0700696 // Choose a random amount of data to copy.
697 size_t copy_len = random() % state.MAX_LEN;
698
699 // Set the second half of ptr to the expected pattern in ptr2.
700 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
701 memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
702 size_t expected_end;
703 if (copy_len > ptr1_len) {
704 memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
705 expected_end = ptr1_len;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400706 } else {
Christopher Ferris950a58e2014-04-04 14:38:18 -0700707 expected_end = copy_len;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400708 }
709
Christopher Ferris950a58e2014-04-04 14:38:18 -0700710 ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400711
Christopher Ferris950a58e2014-04-04 14:38:18 -0700712 // Verify ptr1 was not modified.
713 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
714 // Verify ptr2 contains the expected data.
715 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400716 }
717}
718
719TEST(string, strrchr) {
720 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400721 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400722 for (size_t i = 1; i < state.n; i++) {
723 for (size_t j = 0; j < POS_ITER; j++) {
724 state.NewIteration();
725
726 if (~seek_char > 0) {
727 memset(state.ptr1, ~seek_char, state.len[i]);
728 } else {
729 memset(state.ptr1, '\1', state.len[i]);
730 }
731 state.ptr1[state.len[i] - 1] = '\0';
732
733 int pos = random() % state.MAX_LEN;
734 char* expected;
735 if (pos >= state.len[i] - 1) {
736 if (seek_char == 0) {
737 expected = state.ptr1 + state.len[i] - 1;
738 } else {
739 expected = NULL;
740 }
741 } else {
742 state.ptr1[pos] = seek_char;
743 expected = state.ptr1 + pos;
744 }
745
746 ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
747 }
748 }
749}
750
751TEST(string, memchr) {
752 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400753 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400754 for (size_t i = 0; i < state.n; i++) {
755 for (size_t j = 0; j < POS_ITER; j++) {
756 state.NewIteration();
757
758 memset(state.ptr1, ~seek_char, state.len[i]);
759
760 int pos = random() % state.MAX_LEN;
761 char* expected;
762 if (pos >= state.len[i]) {
763 expected = NULL;
764 } else {
765 state.ptr1[pos] = seek_char;
766 expected = state.ptr1 + pos;
767 }
768
769 ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
770 }
771 }
772}
773
Christopher Ferrise03e1ea2014-07-30 16:06:56 -0700774TEST(string, memchr_zero) {
775 uint8_t* buffer;
776 ASSERT_EQ(0, posix_memalign(reinterpret_cast<void**>(&buffer), 64, 64));
777 memset(buffer, 10, 64);
778 ASSERT_TRUE(NULL == memchr(buffer, 5, 0));
779 ASSERT_TRUE(NULL == memchr(buffer, 10, 0));
780}
781
Anna Tikhonova036154b2012-10-05 15:21:11 +0400782TEST(string, memrchr) {
783 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400784 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400785 for (size_t i = 0; i < state.n; i++) {
786 for (size_t j = 0; j < POS_ITER; j++) {
787 state.NewIteration();
788
789 memset(state.ptr1, ~seek_char, state.len[i]);
790
791 int pos = random() % state.MAX_LEN;
792 char* expected;
793 if (pos >= state.len[i]) {
794 expected = NULL;
795 } else {
796 state.ptr1[pos] = seek_char;
797 expected = state.ptr1 + pos;
798 }
799
800 ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
801 }
802 }
803}
804
805TEST(string, memcmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400806 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400807 for (size_t i = 0; i < state.n; i++) {
808 for (size_t j = 0; j < POS_ITER; j++) {
809 state.NewIteration();
810
811 int c1 = random() & 0xff;
812 int c2 = random() & 0xff;
813 memset(state.ptr1, c1, state.MAX_LEN);
814 memset(state.ptr2, c1, state.MAX_LEN);
815
816 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
817 state.ptr2[pos] = c2;
818
819 int expected = (static_cast<int>(c1) - static_cast<int>(c2));
820 int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
821
822 ASSERT_EQ(signum(expected), signum(actual));
823 }
824 }
825}
826
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400827TEST(string, wmemcmp) {
828 StringTestState<wchar_t> state(SMALL);
829
830 for (size_t i = 0; i < state.n; i++) {
831 for (size_t j = 0; j < POS_ITER; j++) {
832 state.NewIteration();
833
834 long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1;
835 int c1 = rand() & mask;
836 int c2 = rand() & mask;
837 wmemset(state.ptr1, c1, state.MAX_LEN);
838 wmemset(state.ptr2, c1, state.MAX_LEN);
839
840 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
841 state.ptr2[pos] = c2;
842
843 int expected = (static_cast<int>(c1) - static_cast<int>(c2));
844 int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
845
846 ASSERT_EQ(signum(expected), signum(actual));
847 }
848 }
849}
850
Anna Tikhonova036154b2012-10-05 15:21:11 +0400851TEST(string, memcpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400852 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400853 int rand = random() & 255;
854 for (size_t i = 0; i < state.n - 1; i++) {
855 for (size_t j = 0; j < POS_ITER; j++) {
856 state.NewIteration();
857
858 size_t pos = random() % (state.MAX_LEN - state.len[i]);
859
860 memset(state.ptr1, rand, state.len[i]);
861 memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
862
863 memset(state.ptr2, rand, state.len[i]);
864 memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
865 memset(state.ptr2 + pos, '\0', state.len[i]);
866
867 ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
868 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
869 }
870 }
871}
872
873TEST(string, memset) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400874 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400875 char ch = random () & 255;
876 for (size_t i = 0; i < state.n - 1; i++) {
877 for (size_t j = 0; j < POS_ITER; j++) {
878 state.NewIteration();
879
880 memset(state.ptr1, ~ch, state.MAX_LEN);
881 memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
882
883 size_t pos = random () % (state.MAX_LEN - state.len[i]);
884 for (size_t k = pos; k < pos + state.len[i]; k++) {
885 state.ptr1[k] = ch;
886 }
887
888 ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
889
890 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
891 }
892 }
893}
894
895TEST(string, memmove) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400896 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400897 for (size_t i = 0; i < state.n - 1; i++) {
898 for (size_t j = 0; j < POS_ITER; j++) {
899 state.NewIteration();
900
901 memset(state.ptr1, random() & 255, 2 * state.MAX_LEN);
902
903 size_t pos = random() % (state.MAX_LEN - state.len[i]);
904
905 memset(state.ptr1, random() & 255, state.len[i]);
906 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
907 memcpy(state.ptr, state.ptr1, state.len[i]);
908 memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
909
910 ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
911 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
912 }
913 }
914}
915
Varvara Rainchikfce86142014-05-27 12:41:55 +0400916TEST(string, memmove_cache_size) {
917 size_t len = 600000;
918 int max_alignment = 31;
919 int alignments[] = {0, 5, 11, 29, 30};
920 char* ptr = reinterpret_cast<char*>(malloc(sizeof(char) * len));
921 char* ptr1 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len));
922 char* glob_ptr2 = reinterpret_cast<char*>(malloc(2 * sizeof(char) * len + max_alignment));
923 size_t pos = 64;
924
925 ASSERT_TRUE(ptr != NULL);
926 ASSERT_TRUE(ptr1 != NULL);
927 ASSERT_TRUE(glob_ptr2 != NULL);
928
929 for (int i = 0; i < 5; i++) {
930 char* ptr2 = glob_ptr2 + alignments[i];
931 memset(ptr1, random() & 255, 2 * len);
932 memset(ptr1, random() & 255, len);
933 memcpy(ptr2, ptr1, 2 * len);
934 memcpy(ptr, ptr1, len);
935 memcpy(ptr1 + pos, ptr, len);
936
937 ASSERT_TRUE(memmove(ptr2 + pos, ptr, len) == ptr2 + pos);
938 ASSERT_EQ(0, memcmp(ptr2, ptr1, 2 * len));
939 }
940 free(ptr);
941 free(ptr1);
942 free(glob_ptr2);
943}
944
Shu Zhang6c80ccd2014-05-12 18:12:15 +0800945static void verify_memmove(char* src_copy, char* dst, char* src, size_t size) {
946 memset(dst, 0, size);
947 memcpy(src, src_copy, size);
948 ASSERT_EQ(dst, memmove(dst, src, size));
949 ASSERT_EQ(0, memcmp(dst, src_copy, size));
950}
951
952#define MEMMOVE_DATA_SIZE (1024*1024*3)
953
954TEST(string, memmove_check) {
955 char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
956 ASSERT_TRUE(buffer != NULL);
957
958 char* src_data = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
959 ASSERT_TRUE(src_data != NULL);
960 // Initialize to a known pattern to copy into src for each test and
961 // to compare dst against.
962 for (size_t i = 0; i < MEMMOVE_DATA_SIZE; i++) {
963 src_data[i] = (i + 1) % 255;
964 }
965
966 // Check all different dst offsets between 0 and 127 inclusive.
967 char* src = buffer;
968 for (size_t i = 0; i < 127; i++) {
969 char* dst = buffer + 256 + i;
970 // Small copy.
971 verify_memmove(src_data, dst, src, 1024);
972
973 // Medium copy.
974 verify_memmove(src_data, dst, src, 64 * 1024);
975
976 // Medium copy.
977 verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
978 }
979
980 // Check all leftover size offsets between 1 and 127 inclusive.
981 char* dst = buffer + 256;
982 src = buffer;
983 for (size_t size = 1; size < 127; size++) {
984 // Small copy.
985 verify_memmove(src_data, dst, src, 1024);
986
987 // Medium copy.
988 verify_memmove(src_data, dst, src, 64 * 1024);
989
990 // Large copy.
991 verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
992 }
993}
994
Anna Tikhonova036154b2012-10-05 15:21:11 +0400995TEST(string, bcopy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400996 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400997 for (size_t i = 0; i < state.n; i++) {
998 for (size_t j = 0; j < POS_ITER; j++) {
999 state.NewIteration();
1000
1001 memset(state.ptr1, random() & 255, state.MAX_LEN);
1002 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN);
1003 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
1004
1005 size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
1006 memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
1007
1008 bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
1009 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
1010 }
1011 }
1012}
1013
1014TEST(string, bzero) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +04001015 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +04001016 for (size_t j = 0; j < ITER; j++) {
1017 state.NewIteration();
1018
1019 memset(state.ptr1, random() & 255, state.MAX_LEN);
1020
1021 size_t start = random() % state.MAX_LEN;
1022 size_t end = start + random() % (state.MAX_LEN - start);
1023
1024 memcpy(state.ptr2, state.ptr1, start);
1025 memset(state.ptr2 + start, '\0', end - start);
1026 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
1027
1028 bzero(state.ptr1 + start, end - start);
1029
1030 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
1031 }
1032}
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001033
1034static void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1035 memset(src, (len % 255) + 1, len);
1036 memset(dst, 0, len);
1037
1038 ASSERT_EQ(dst, memcpy(dst, src, len));
1039 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1040}
1041
1042TEST(string, memcpy_align) {
1043 RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
1044}
1045
1046TEST(string, memcpy_overread) {
1047 RunSrcDstBufferOverreadTest(DoMemcpyTest);
1048}
1049
Shu Zhang6c80ccd2014-05-12 18:12:15 +08001050static void DoMemmoveTest(uint8_t* src, uint8_t* dst, size_t len) {
1051 memset(src, (len % 255) + 1, len);
1052 memset(dst, 0, len);
1053
1054 ASSERT_EQ(dst, memmove(dst, src, len));
1055 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1056}
1057
1058TEST(string, memmove_align) {
1059 RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
1060}
1061
1062TEST(string, memmove_overread) {
1063 RunSrcDstBufferOverreadTest(DoMemmoveTest);
1064}
1065
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001066static void DoMemsetTest(uint8_t* buf, size_t len) {
1067 for (size_t i = 0; i < len; i++) {
1068 buf[i] = 0;
1069 }
1070 int value = (len % 255) + 1;
1071 ASSERT_EQ(buf, memset(buf, value, len));
1072 for (size_t i = 0; i < len; i++) {
1073 ASSERT_EQ(value, buf[i]);
1074 }
1075}
1076
1077TEST(string, memset_align) {
1078 RunSingleBufferAlignTest(LARGE, DoMemsetTest);
1079}
1080
1081static void DoStrlenTest(uint8_t* buf, size_t len) {
1082 if (len >= 1) {
1083 memset(buf, (32 + (len % 96)), len - 1);
1084 buf[len-1] = '\0';
1085 ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf)));
1086 }
1087}
1088
1089TEST(string, strlen_align) {
1090 RunSingleBufferAlignTest(LARGE, DoStrlenTest);
1091}
1092
1093TEST(string, strlen_overread) {
1094 RunSingleBufferOverreadTest(DoStrlenTest);
1095}
1096
1097static void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1098 if (len >= 1) {
1099 memset(src, (32 + (len % 96)), len - 1);
1100 src[len-1] = '\0';
1101 memset(dst, 0, len);
1102 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst),
1103 reinterpret_cast<char*>(src))));
1104 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1105 }
1106}
1107
1108TEST(string, strcpy_align) {
1109 RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
1110}
1111
1112TEST(string, strcpy_overread) {
1113 RunSrcDstBufferOverreadTest(DoStrcpyTest);
1114}
1115
Christopher Ferris950a58e2014-04-04 14:38:18 -07001116static void DoStpcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
1117 if (len >= 1) {
1118 memset(src, (32 + (len % 96)), len - 1);
1119 src[len-1] = '\0';
1120 memset(dst, 0, len);
1121 ASSERT_EQ(dst+len-1, reinterpret_cast<uint8_t*>(stpcpy(reinterpret_cast<char*>(dst),
1122 reinterpret_cast<char*>(src))));
1123 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1124 }
1125}
1126
1127TEST(string, stpcpy_align) {
1128 RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest);
1129}
1130
1131TEST(string, stpcpy_overread) {
1132 RunSrcDstBufferOverreadTest(DoStpcpyTest);
1133}
1134
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001135// Use our own incrementer to cut down on the total number of calls.
Christopher Ferrise5bbb6b2013-12-03 18:39:10 -08001136static size_t LargeSetIncrement(size_t len) {
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001137 if (len >= 4096) {
1138 return 4096;
1139 } else if (len >= 1024) {
1140 return 1024;
1141 } else if (len >= 256) {
1142 return 256;
1143 }
1144 return 1;
1145}
1146
1147#define STRCAT_DST_LEN 128
1148
1149static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) {
1150 if (len >= 1) {
1151 int value = 32 + (len % 96);
1152 memset(src, value, len - 1);
1153 src[len-1] = '\0';
1154
1155 if (len >= STRCAT_DST_LEN) {
1156 // Create a small buffer for doing quick compares in each loop.
1157 uint8_t cmp_buf[STRCAT_DST_LEN];
1158 // Make sure dst string contains a different value then the src string.
1159 int value2 = 32 + (value + 2) % 96;
1160 memset(cmp_buf, value2, sizeof(cmp_buf));
1161
1162 for (size_t i = 1; i <= STRCAT_DST_LEN; i++) {
1163 memset(dst, value2, i-1);
1164 memset(dst+i-1, 0, len-i);
1165 src[len-i] = '\0';
1166 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
1167 reinterpret_cast<char*>(src))));
1168 ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
1169 ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
1170 }
1171 } else {
1172 dst[0] = '\0';
1173 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
1174 reinterpret_cast<char*>(src))));
1175 ASSERT_TRUE(memcmp(src, dst, len) == 0);
1176 }
1177 }
1178}
1179
1180TEST(string, strcat_align) {
Christopher Ferrise5bbb6b2013-12-03 18:39:10 -08001181 RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement);
Christopher Ferrisb687ad32013-11-06 17:32:11 -08001182}
1183
1184TEST(string, strcat_overread) {
1185 RunSrcDstBufferOverreadTest(DoStrcatTest);
1186}
Christopher Ferrise5bbb6b2013-12-03 18:39:10 -08001187
1188static void DoStrcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
1189 if (len >= 1) {
1190 memset(buf1, (32 + (len % 96)), len - 1);
1191 buf1[len-1] = '\0';
1192 memset(buf2, (32 + (len % 96)), len - 1);
1193 buf2[len-1] = '\0';
1194 ASSERT_EQ(0, strcmp(reinterpret_cast<char*>(buf1),
1195 reinterpret_cast<char*>(buf2)));
1196 }
1197}
1198
1199static void DoStrcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
1200 // Do string length differences.
1201 int c = (32 + (len1 % 96));
1202 memset(buf1, c, len1 - 1);
1203 buf1[len1-1] = '\0';
1204 memset(buf2, c, len2 - 1);
1205 buf2[len2-1] = '\0';
1206 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1207 reinterpret_cast<char*>(buf2)));
1208
1209 // Do single character differences.
1210 size_t len;
1211 if (len1 > len2) {
1212 len = len2;
1213 } else {
1214 len = len1;
1215 }
1216 // Need at least a two character buffer to do this test.
1217 if (len > 1) {
1218 buf1[len-1] = '\0';
1219 buf2[len-1] = '\0';
1220 int diff_c = (c + 1) % 96;
1221
1222 buf1[len-2] = diff_c;
1223 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1224 reinterpret_cast<char*>(buf2)));
1225
1226 buf1[len-2] = c;
1227 buf2[len-2] = diff_c;
1228 ASSERT_NE(0, strcmp(reinterpret_cast<char*>(buf1),
1229 reinterpret_cast<char*>(buf2)));
1230 }
1231}
1232
1233TEST(string, strcmp_align) {
1234 RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement);
1235}
1236
1237TEST(string, strcmp_overread) {
1238 RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest);
1239}
1240
1241static void DoMemcmpTest(uint8_t* buf1, uint8_t* buf2, size_t len) {
1242 memset(buf1, len+1, len);
1243 memset(buf2, len+1, len);
1244 ASSERT_EQ(0, memcmp(buf1, buf2, len));
1245}
1246
1247static void DoMemcmpFailTest(uint8_t* buf1, uint8_t* buf2, size_t len1, size_t len2) {
1248 size_t len;
1249 if (len1 > len2) {
1250 len = len2;
1251 } else {
1252 len = len1;
1253 }
1254
1255 memset(buf1, len2+1, len);
1256 buf1[len-1] = len2;
1257 memset(buf2, len2+1, len);
1258 ASSERT_NE(0, memcmp(buf1, buf2, len));
1259
1260 buf1[len-1] = len2+1;
1261 buf2[len-1] = len2;
1262 ASSERT_NE(0, memcmp(buf1, buf2, len));
1263}
1264
1265TEST(string, memcmp_align) {
1266 RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement);
1267}
1268
1269TEST(string, memcmp_overread) {
1270 RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
1271}
Christopher Ferris3a657d02014-06-27 12:33:22 -07001272
1273static void DoStrchrTest(uint8_t* buf, size_t len) {
1274 if (len >= 1) {
1275 char value = 32 + (len % 96);
1276 char search_value = 33 + (len % 96);
1277 memset(buf, value, len - 1);
1278 buf[len-1] = '\0';
1279 ASSERT_EQ(NULL, strchr(reinterpret_cast<char*>(buf), search_value));
1280 ASSERT_EQ(reinterpret_cast<char*>(&buf[len-1]), strchr(reinterpret_cast<char*>(buf), '\0'));
1281 if (len >= 2) {
1282 buf[0] = search_value;
1283 ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strchr(reinterpret_cast<char*>(buf), search_value));
1284 buf[0] = value;
1285 buf[len-2] = search_value;
1286 ASSERT_EQ(reinterpret_cast<char*>(&buf[len-2]), strchr(reinterpret_cast<char*>(buf), search_value));
1287 }
1288 }
1289}
1290
1291TEST(string, strchr_align) {
1292 RunSingleBufferAlignTest(MEDIUM, DoStrchrTest);
1293}
1294
1295TEST(string, strchr_overread) {
1296 RunSingleBufferOverreadTest(DoStrchrTest);
1297}
Elliott Hughes09c39d62014-08-19 14:30:30 -07001298
1299static void TestBasename(const char* in, const char* expected_out) {
1300 errno = 0;
1301 const char* out = basename(in);
1302 ASSERT_STREQ(expected_out, out) << in;
1303 ASSERT_EQ(0, errno) << in;
1304}
1305
1306TEST(string, __gnu_basename) {
1307 TestBasename("", "");
1308 TestBasename("/usr/lib", "lib");
1309 TestBasename("/usr/", "");
1310 TestBasename("usr", "usr");
1311 TestBasename("/", "");
1312 TestBasename(".", ".");
1313 TestBasename("..", "..");
1314 TestBasename("///", "");
1315 TestBasename("//usr//lib//", "");
1316}