blob: be46dc98f6dda5bcb93d10fc8147f4032b9e37a0 [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>
Anna Tikhonova036154b2012-10-05 15:21:11 +040020#include <math.h>
Irina Tirdeab5f053b2012-09-08 09:17:54 +030021#include <string.h>
22
Christopher Ferrisb687ad32013-11-06 17:32:11 -080023#include "buffer_tests.h"
24
Anna Tikhonova036154b2012-10-05 15:21:11 +040025#define KB 1024
26#define SMALL 1*KB
Christopher Ferrisb687ad32013-11-06 17:32:11 -080027#define MEDIUM 4*KB
Anna Tikhonova036154b2012-10-05 15:21:11 +040028#define LARGE 64*KB
29
30static int signum(int i) {
31 if (i < 0) {
32 return -1;
33 } else if (i > 0) {
34 return 1;
35 }
36 return 0;
37}
38
Irina Tirdeab5f053b2012-09-08 09:17:54 +030039TEST(string, strerror) {
40 // Valid.
41 ASSERT_STREQ("Success", strerror(0));
42 ASSERT_STREQ("Operation not permitted", strerror(1));
43
44 // Invalid.
Elliott Hughese6e60062013-01-10 16:01:59 -080045 ASSERT_STREQ("Unknown error -1", strerror(-1));
Irina Tirdeab5f053b2012-09-08 09:17:54 +030046 ASSERT_STREQ("Unknown error 1234", strerror(1234));
47}
48
Elliott Hughesad88a082012-10-24 18:37:21 -070049#if __BIONIC__ // glibc's strerror isn't thread safe, only its strsignal.
50
51static 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}
55
Irina Tirdeab5f053b2012-09-08 09:17:54 +030056TEST(string, strerror_concurrent) {
57 const char* strerror1001 = strerror(1001);
58 ASSERT_STREQ("Unknown error 1001", strerror1001);
59
60 pthread_t t;
61 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL));
62 void* result;
63 ASSERT_EQ(0, pthread_join(t, &result));
64 ASSERT_TRUE(static_cast<bool>(result));
65
66 ASSERT_STREQ("Unknown error 1001", strerror1001);
67}
Elliott Hughesad88a082012-10-24 18:37:21 -070068
Irina Tirdeab5f053b2012-09-08 09:17:54 +030069#endif
70
71#if __BIONIC__ // glibc's strerror_r doesn't even have the same signature as the POSIX one.
72TEST(string, strerror_r) {
73 char buf[256];
74
75 // Valid.
76 ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf)));
77 ASSERT_STREQ("Success", buf);
78 ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf)));
79 ASSERT_STREQ("Operation not permitted", buf);
80
81 // Invalid.
82 ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf)));
Nick Kralevich60605892013-01-15 10:35:09 -080083 ASSERT_STREQ("Unknown error -1", buf);
Irina Tirdeab5f053b2012-09-08 09:17:54 +030084 ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf)));
85 ASSERT_STREQ("Unknown error 1234", buf);
86
87 // Buffer too small.
88 ASSERT_EQ(-1, strerror_r(0, buf, 2));
89 ASSERT_EQ(ERANGE, errno);
90}
91#endif
92
93TEST(string, strsignal) {
94 // A regular signal.
95 ASSERT_STREQ("Hangup", strsignal(1));
96
97 // A real-time signal.
98#ifdef __GLIBC__ // glibc reserves real-time signals for internal use, and doesn't count those.
99 ASSERT_STREQ("Real-time signal 14", strsignal(48));
100#else
101 ASSERT_STREQ("Real-time signal 16", strsignal(48));
102#endif
103
104 // Errors.
105 ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
106 ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small.
107 ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large.
108}
109
Elliott Hughesad88a082012-10-24 18:37:21 -0700110static void* ConcurrentStrSignalFn(void*) {
Irina Tirdeab5f053b2012-09-08 09:17:54 +0300111 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
112 return reinterpret_cast<void*>(equal);
113}
114
115TEST(string, strsignal_concurrent) {
116 const char* strsignal1001 = strsignal(1001);
117 ASSERT_STREQ("Unknown signal 1001", strsignal1001);
118
119 pthread_t t;
120 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL));
121 void* result;
122 ASSERT_EQ(0, pthread_join(t, &result));
123 ASSERT_TRUE(static_cast<bool>(result));
124
125 ASSERT_STREQ("Unknown signal 1001", strsignal1001);
126}
Anna Tikhonova036154b2012-10-05 15:21:11 +0400127
128// TODO: where did these numbers come from?
129#define POS_ITER 10
130#define ITER 500
131
132// For every length we want to test, vary and change alignment
133// of allocated memory, fill it with some values, calculate
134// expected result and then run function and compare what we got.
135// These tests contributed by Intel Corporation.
136// TODO: make these tests more intention-revealing and less random.
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400137template<class Character>
Anna Tikhonova036154b2012-10-05 15:21:11 +0400138struct StringTestState {
139 StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) {
140 int max_alignment = 64;
141
142 // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN".
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400143 glob_ptr = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
144 glob_ptr1 = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
145 glob_ptr2 = reinterpret_cast<Character*>(valloc(2 * sizeof(Character) * MAX_LEN + max_alignment));
Anna Tikhonova036154b2012-10-05 15:21:11 +0400146
147 InitLenArray();
148
149 srandom(1234);
150 }
151
152 ~StringTestState() {
153 free(glob_ptr);
154 free(glob_ptr1);
155 free(glob_ptr2);
156 }
157
158 void NewIteration() {
159 int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 };
160 int usable_alignments = 10;
161 int align1 = alignments[random() % (usable_alignments - 1)];
162 int align2 = alignments[random() % (usable_alignments - 1)];
163
164 ptr = glob_ptr + align1;
165 ptr1 = glob_ptr1 + align1;
166 ptr2 = glob_ptr2 + align2;
167 }
168
169 const size_t MAX_LEN;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400170 Character *ptr, *ptr1, *ptr2;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400171 size_t n;
172 int len[ITER + 1];
173
174 private:
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400175 Character *glob_ptr, *glob_ptr1, *glob_ptr2;
Anna Tikhonova036154b2012-10-05 15:21:11 +0400176
177 // Calculate input lengths and fill state.len with them.
178 // Test small lengths with more density than big ones. Manually push
179 // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats.
180 // Return number of lengths to test.
181 void InitLenArray() {
182 n = 0;
183 len[n++] = 0;
184 for (size_t i = 1; i < ITER; ++i) {
185 int l = (int) exp(log((double) MAX_LEN) * i / ITER);
186 if (l != len[n - 1]) {
187 len[n++] = l;
188 }
189 }
190 len[n++] = MAX_LEN;
191 }
192};
193
194TEST(string, strcat) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400195 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400196 for (size_t i = 1; i < state.n; i++) {
197 for (size_t j = 0; j < POS_ITER; j++) {
198 state.NewIteration();
199
200 memset(state.ptr2, '\2', state.MAX_LEN);
201 state.ptr2[state.MAX_LEN - 1] = '\0';
202 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
203
204 memset(state.ptr1, random() & 255, state.len[i]);
205 state.ptr1[random() % state.len[i]] = '\0';
206 state.ptr1[state.len[i] - 1] = '\0';
207
208 strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1);
209
210 EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2);
211 EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0);
212 }
213 }
214}
215
Nick Kralevich13476de2013-06-03 10:58:06 -0700216// one byte target with "\0" source
217TEST(string, strcpy2) {
218 char buf[1];
219 char* orig = strdup("");
220 strcpy(buf, orig);
221 ASSERT_EQ('\0', buf[0]);
222 free(orig);
223}
224
225// multibyte target where we under fill target
226TEST(string, strcpy3) {
227 char buf[10];
228 char* orig = strdup("12345");
229 memset(buf, 'A', sizeof(buf));
230 strcpy(buf, orig);
231 ASSERT_EQ('1', buf[0]);
232 ASSERT_EQ('2', buf[1]);
233 ASSERT_EQ('3', buf[2]);
234 ASSERT_EQ('4', buf[3]);
235 ASSERT_EQ('5', buf[4]);
236 ASSERT_EQ('\0', buf[5]);
237 ASSERT_EQ('A', buf[6]);
238 ASSERT_EQ('A', buf[7]);
239 ASSERT_EQ('A', buf[8]);
240 ASSERT_EQ('A', buf[9]);
241 free(orig);
242}
243
244// multibyte target where we fill target exactly
245TEST(string, strcpy4) {
246 char buf[10];
247 char* orig = strdup("123456789");
248 memset(buf, 'A', sizeof(buf));
249 strcpy(buf, orig);
250 ASSERT_EQ('1', buf[0]);
251 ASSERT_EQ('2', buf[1]);
252 ASSERT_EQ('3', buf[2]);
253 ASSERT_EQ('4', buf[3]);
254 ASSERT_EQ('5', buf[4]);
255 ASSERT_EQ('6', buf[5]);
256 ASSERT_EQ('7', buf[6]);
257 ASSERT_EQ('8', buf[7]);
258 ASSERT_EQ('9', buf[8]);
259 ASSERT_EQ('\0', buf[9]);
260 free(orig);
261}
262
Nick Kralevichcf870192013-05-30 16:48:53 -0700263TEST(string, strcat2) {
264 char buf[10];
265 memset(buf, 'A', sizeof(buf));
266 buf[0] = 'a';
267 buf[1] = '\0';
268 char* res = strcat(buf, "01234");
269 ASSERT_EQ(buf, res);
270 ASSERT_EQ('a', buf[0]);
271 ASSERT_EQ('0', buf[1]);
272 ASSERT_EQ('1', buf[2]);
273 ASSERT_EQ('2', buf[3]);
274 ASSERT_EQ('3', buf[4]);
275 ASSERT_EQ('4', buf[5]);
276 ASSERT_EQ('\0', buf[6]);
277 ASSERT_EQ('A', buf[7]);
278 ASSERT_EQ('A', buf[8]);
279 ASSERT_EQ('A', buf[9]);
280}
281
282TEST(string, strcat3) {
283 char buf[10];
284 memset(buf, 'A', sizeof(buf));
285 buf[0] = 'a';
286 buf[1] = '\0';
287 char* res = strcat(buf, "01234567");
288 ASSERT_EQ(buf, res);
289 ASSERT_EQ('a', buf[0]);
290 ASSERT_EQ('0', buf[1]);
291 ASSERT_EQ('1', buf[2]);
292 ASSERT_EQ('2', buf[3]);
293 ASSERT_EQ('3', buf[4]);
294 ASSERT_EQ('4', buf[5]);
295 ASSERT_EQ('5', buf[6]);
296 ASSERT_EQ('6', buf[7]);
297 ASSERT_EQ('7', buf[8]);
298 ASSERT_EQ('\0', buf[9]);
299}
300
301TEST(string, strncat2) {
302 char buf[10];
303 memset(buf, 'A', sizeof(buf));
304 buf[0] = 'a';
305 buf[1] = '\0';
306 char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1);
307 ASSERT_EQ(buf, res);
308 ASSERT_EQ('a', buf[0]);
309 ASSERT_EQ('0', buf[1]);
310 ASSERT_EQ('1', buf[2]);
311 ASSERT_EQ('2', buf[3]);
312 ASSERT_EQ('3', buf[4]);
313 ASSERT_EQ('4', buf[5]);
314 ASSERT_EQ('\0', buf[6]);
315 ASSERT_EQ('A', buf[7]);
316 ASSERT_EQ('A', buf[8]);
317 ASSERT_EQ('A', buf[9]);
318}
319
320TEST(string, strncat3) {
321 char buf[10];
322 memset(buf, 'A', sizeof(buf));
323 buf[0] = 'a';
324 buf[1] = '\0';
325 char* res = strncat(buf, "0123456789", 5);
326 ASSERT_EQ(buf, res);
327 ASSERT_EQ('a', buf[0]);
328 ASSERT_EQ('0', buf[1]);
329 ASSERT_EQ('1', buf[2]);
330 ASSERT_EQ('2', buf[3]);
331 ASSERT_EQ('3', buf[4]);
332 ASSERT_EQ('4', buf[5]);
333 ASSERT_EQ('\0', buf[6]);
334 ASSERT_EQ('A', buf[7]);
335 ASSERT_EQ('A', buf[8]);
336 ASSERT_EQ('A', buf[9]);
337}
338
339TEST(string, strncat4) {
340 char buf[10];
341 memset(buf, 'A', sizeof(buf));
342 buf[0] = 'a';
343 buf[1] = '\0';
344 char* res = strncat(buf, "01234567", 8);
345 ASSERT_EQ(buf, res);
346 ASSERT_EQ('a', buf[0]);
347 ASSERT_EQ('0', buf[1]);
348 ASSERT_EQ('1', buf[2]);
349 ASSERT_EQ('2', buf[3]);
350 ASSERT_EQ('3', buf[4]);
351 ASSERT_EQ('4', buf[5]);
352 ASSERT_EQ('5', buf[6]);
353 ASSERT_EQ('6', buf[7]);
354 ASSERT_EQ('7', buf[8]);
355 ASSERT_EQ('\0', buf[9]);
356}
357
358TEST(string, strncat5) {
359 char buf[10];
360 memset(buf, 'A', sizeof(buf));
361 buf[0] = 'a';
362 buf[1] = '\0';
363 char* res = strncat(buf, "01234567", 9);
364 ASSERT_EQ(buf, res);
365 ASSERT_EQ('a', buf[0]);
366 ASSERT_EQ('0', buf[1]);
367 ASSERT_EQ('1', buf[2]);
368 ASSERT_EQ('2', buf[3]);
369 ASSERT_EQ('3', buf[4]);
370 ASSERT_EQ('4', buf[5]);
371 ASSERT_EQ('5', buf[6]);
372 ASSERT_EQ('6', buf[7]);
373 ASSERT_EQ('7', buf[8]);
374 ASSERT_EQ('\0', buf[9]);
375}
376
Nick Kralevich4f40e512013-04-19 16:54:22 -0700377TEST(string, strchr_with_0) {
378 char buf[10];
379 const char* s = "01234";
380 memcpy(buf, s, strlen(s) + 1);
381 EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
382}
383
Anna Tikhonova036154b2012-10-05 15:21:11 +0400384TEST(string, strchr) {
385 int seek_char = random() & 255;
386
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400387 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400388 for (size_t i = 1; i < state.n; i++) {
389 for (size_t j = 0; j < POS_ITER; j++) {
390 state.NewIteration();
391
392 if (~seek_char > 0) {
393 memset(state.ptr1, ~seek_char, state.len[i]);
394 } else {
395 memset(state.ptr1, '\1', state.len[i]);
396 }
397 state.ptr1[state.len[i] - 1] = '\0';
398
399 int pos = random() % state.MAX_LEN;
400 char* expected;
401 if (pos >= state.len[i] - 1) {
402 if (seek_char == 0) {
403 expected = state.ptr1 + state.len[i] - 1;
404 } else {
405 expected = NULL;
406 }
407 } else {
408 state.ptr1[pos] = seek_char;
409 expected = state.ptr1 + pos;
410 }
411
412 ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected);
413 }
414 }
415}
416
417TEST(string, strcmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400418 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400419 for (size_t i = 1; i < state.n; i++) {
420 for (size_t j = 0; j < POS_ITER; j++) {
421 state.NewIteration();
422
423 memset(state.ptr1, 'v', state.MAX_LEN);
424 memset(state.ptr2, 'n', state.MAX_LEN);
425 state.ptr1[state.len[i] - 1] = '\0';
426 state.ptr2[state.len[i] - 1] = '\0';
427
428 int pos = 1 + (random() % (state.MAX_LEN - 1));
429 int actual;
430 int expected;
431 if (pos >= state.len[i] - 1) {
432 memcpy(state.ptr1, state.ptr2, state.len[i]);
433 expected = 0;
434 actual = strcmp(state.ptr1, state.ptr2);
435 } else {
436 memcpy(state.ptr1, state.ptr2, pos);
437 if (state.ptr1[pos] > state.ptr2[pos]) {
438 expected = 1;
439 } else if (state.ptr1[pos] == state.ptr2[pos]) {
440 state.ptr1[pos + 1] = '\0';
441 state.ptr2[pos + 1] = '\0';
442 expected = 0;
443 } else {
444 expected = -1;
445 }
446 actual = strcmp(state.ptr1, state.ptr2);
447 }
448
449 ASSERT_EQ(expected, signum(actual));
450 }
451 }
452}
453
454TEST(string, strcpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400455 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400456 for (size_t j = 0; j < POS_ITER; j++) {
457 state.NewIteration();
458
459 size_t pos = random() % state.MAX_LEN;
460
461 memset(state.ptr1, '\2', pos);
462 state.ptr1[pos] = '\0';
463 state.ptr1[state.MAX_LEN - 1] = '\0';
464
465 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
466
467 memset(state.ptr2, '\1', state.MAX_LEN);
468 state.ptr2[state.MAX_LEN - 1] = '\0';
469
470 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
471 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
472 state.ptr[2 * state.MAX_LEN - 1] = '\0';
473
474 ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2);
475 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 ||
476 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
477 }
478}
479
Nick Kralevichdcab1b22013-01-10 17:12:29 -0800480
481#if __BIONIC__
Anna Tikhonova036154b2012-10-05 15:21:11 +0400482TEST(string, strlcat) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400483 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400484 for (size_t i = 0; i < state.n; i++) {
485 for (size_t j = 0; j < POS_ITER; j++) {
486 state.NewIteration();
487
488 memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]);
489 state.ptr2[state.MAX_LEN - 1] = '\0';
490 memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]);
491
492 int pos = random() % state.MAX_LEN;
493 memset(state.ptr1, '\3', pos);
494 state.ptr1[pos] = '\0';
495 if (pos < state.len[i]) {
496 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1);
497 } else {
498 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]);
499 state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0';
500 }
501
502 strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]);
503
504 ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0);
505 }
506 }
507}
508#endif
509
510#if __BIONIC__
511TEST(string, strlcpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400512 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400513 for (size_t j = 0; j < POS_ITER; j++) {
514 state.NewIteration();
515
516 int rand = random() & 255;
517 if (rand < 1) {
518 rand = 1;
519 }
520 memset(state.ptr1, rand, state.MAX_LEN);
521
522 size_t pos = random() % state.MAX_LEN;
523 if (pos < state.MAX_LEN) {
524 state.ptr1[pos] = '\0';
525 }
526 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
527
528 memset(state.ptr2, random() & 255, state.MAX_LEN);
529 memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN);
530
531 if (pos > state.MAX_LEN - 1) {
532 memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN);
533 state.ptr[2 * state.MAX_LEN - 1] = '\0';
534 } else {
535 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
536 }
537
538 ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1));
539 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) ||
540 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
541 }
542}
543#endif
544
545TEST(string, strncat) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400546 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400547 for (size_t i = 1; i < state.n; i++) {
548 for (size_t j = 0; j < POS_ITER; j++) {
549 state.NewIteration();
550
551 memset(state.ptr2, '\2', state.MAX_LEN);
552 state.ptr2[state.MAX_LEN - 1] = '\0';
553 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN);
554
555 memset(state.ptr1, random() & 255, state.len[i]);
556 state.ptr1[random() % state.len[i]] = '\0';
557 state.ptr1[state.len[i] - 1] = '\0';
558
559 size_t pos = strlen(state.ptr1);
560
561 size_t actual = random() % state.len[i];
562 strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos));
563 state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0';
564
565 ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2);
566 ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0);
567 }
568 }
569}
570
571TEST(string, strncmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400572 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400573 for (size_t i = 1; i < state.n; i++) {
574 for (size_t j = 0; j < POS_ITER; j++) {
575 state.NewIteration();
576
577 memset(state.ptr1, 'v', state.MAX_LEN);
578 memset(state.ptr2, 'n', state.MAX_LEN);
579 state.ptr1[state.len[i] - 1] = '\0';
580 state.ptr2[state.len[i] - 1] = '\0';
581
582 int pos = 1 + (random() % (state.MAX_LEN - 1));
583 int actual;
584 int expected;
585 if (pos >= state.len[i] - 1) {
586 memcpy(state.ptr1, state.ptr2, state.len[i]);
587 expected = 0;
588 actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
589 } else {
590 memcpy(state.ptr1, state.ptr2, pos);
591 if (state.ptr1[pos] > state.ptr2[pos]) {
592 expected = 1;
593 } else if (state.ptr1[pos] == state.ptr2[pos]) {
594 state.ptr1[pos + 1] = '\0';
595 state.ptr2[pos + 1] = '\0';
596 expected = 0;
597 } else {
598 expected = -1;
599 }
600 actual = strncmp(state.ptr1, state.ptr2, state.len[i]);
601 }
602
603 ASSERT_EQ(expected, signum(actual));
604 }
605 }
606}
607
608TEST(string, strncpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400609 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400610 for (size_t j = 0; j < ITER; j++) {
611 state.NewIteration();
612
613 memset(state.ptr1, random() & 255, state.MAX_LEN);
614 state.ptr1[random () % state.MAX_LEN] = '\0';
615 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
616
617 memset(state.ptr2, '\1', state.MAX_LEN);
618
619 size_t pos;
620 if (memchr(state.ptr1, 0, state.MAX_LEN)) {
621 pos = strlen(state.ptr1);
622 } else {
623 pos = state.MAX_LEN - 1;
624 }
625
626 memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN);
627 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1);
628
629 ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2);
630 ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 ||
631 memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0);
632 }
633}
634
635TEST(string, strrchr) {
636 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400637 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400638 for (size_t i = 1; i < state.n; i++) {
639 for (size_t j = 0; j < POS_ITER; j++) {
640 state.NewIteration();
641
642 if (~seek_char > 0) {
643 memset(state.ptr1, ~seek_char, state.len[i]);
644 } else {
645 memset(state.ptr1, '\1', state.len[i]);
646 }
647 state.ptr1[state.len[i] - 1] = '\0';
648
649 int pos = random() % state.MAX_LEN;
650 char* expected;
651 if (pos >= state.len[i] - 1) {
652 if (seek_char == 0) {
653 expected = state.ptr1 + state.len[i] - 1;
654 } else {
655 expected = NULL;
656 }
657 } else {
658 state.ptr1[pos] = seek_char;
659 expected = state.ptr1 + pos;
660 }
661
662 ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected);
663 }
664 }
665}
666
667TEST(string, memchr) {
668 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400669 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400670 for (size_t i = 0; i < state.n; i++) {
671 for (size_t j = 0; j < POS_ITER; j++) {
672 state.NewIteration();
673
674 memset(state.ptr1, ~seek_char, state.len[i]);
675
676 int pos = random() % state.MAX_LEN;
677 char* expected;
678 if (pos >= state.len[i]) {
679 expected = NULL;
680 } else {
681 state.ptr1[pos] = seek_char;
682 expected = state.ptr1 + pos;
683 }
684
685 ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected);
686 }
687 }
688}
689
690TEST(string, memrchr) {
691 int seek_char = random() & 255;
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400692 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400693 for (size_t i = 0; i < state.n; i++) {
694 for (size_t j = 0; j < POS_ITER; j++) {
695 state.NewIteration();
696
697 memset(state.ptr1, ~seek_char, state.len[i]);
698
699 int pos = random() % state.MAX_LEN;
700 char* expected;
701 if (pos >= state.len[i]) {
702 expected = NULL;
703 } else {
704 state.ptr1[pos] = seek_char;
705 expected = state.ptr1 + pos;
706 }
707
708 ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected);
709 }
710 }
711}
712
713TEST(string, memcmp) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400714 StringTestState<char> state(SMALL);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400715 for (size_t i = 0; i < state.n; i++) {
716 for (size_t j = 0; j < POS_ITER; j++) {
717 state.NewIteration();
718
719 int c1 = random() & 0xff;
720 int c2 = random() & 0xff;
721 memset(state.ptr1, c1, state.MAX_LEN);
722 memset(state.ptr2, c1, state.MAX_LEN);
723
724 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
725 state.ptr2[pos] = c2;
726
727 int expected = (static_cast<int>(c1) - static_cast<int>(c2));
728 int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN);
729
730 ASSERT_EQ(signum(expected), signum(actual));
731 }
732 }
733}
734
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400735#if defined(__BIONIC__)
736extern "C" int __memcmp16(const unsigned short *ptr1, const unsigned short *ptr2, size_t n);
737
738TEST(string, __memcmp16) {
739 StringTestState<unsigned short> state(SMALL);
740
741 for (size_t i = 0; i < state.n; i++) {
742 for (size_t j = 0; j < POS_ITER; j++) {
743 state.NewIteration();
744
745 unsigned short mask = 0xffff;
746 unsigned short c1 = rand() & mask;
747 unsigned short c2 = rand() & mask;
748
749 std::fill(state.ptr1, state.ptr1 + state.MAX_LEN, c1);
750 std::fill(state.ptr2, state.ptr2 + state.MAX_LEN, c1);
751
752 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
753 state.ptr2[pos] = c2;
754
755 int expected = (static_cast<unsigned short>(c1) - static_cast<unsigned short>(c2));
756 int actual = __memcmp16(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
757
758 ASSERT_EQ(expected, actual);
759 }
760 }
761}
762#endif
763
764TEST(string, wmemcmp) {
765 StringTestState<wchar_t> state(SMALL);
766
767 for (size_t i = 0; i < state.n; i++) {
768 for (size_t j = 0; j < POS_ITER; j++) {
769 state.NewIteration();
770
771 long long mask = ((long long) 1 << 8 * sizeof(wchar_t)) - 1;
772 int c1 = rand() & mask;
773 int c2 = rand() & mask;
774 wmemset(state.ptr1, c1, state.MAX_LEN);
775 wmemset(state.ptr2, c1, state.MAX_LEN);
776
777 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
778 state.ptr2[pos] = c2;
779
780 int expected = (static_cast<int>(c1) - static_cast<int>(c2));
781 int actual = wmemcmp(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);
782
783 ASSERT_EQ(signum(expected), signum(actual));
784 }
785 }
786}
787
Anna Tikhonova036154b2012-10-05 15:21:11 +0400788TEST(string, memcpy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400789 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400790 int rand = random() & 255;
791 for (size_t i = 0; i < state.n - 1; i++) {
792 for (size_t j = 0; j < POS_ITER; j++) {
793 state.NewIteration();
794
795 size_t pos = random() % (state.MAX_LEN - state.len[i]);
796
797 memset(state.ptr1, rand, state.len[i]);
798 memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
799
800 memset(state.ptr2, rand, state.len[i]);
801 memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]);
802 memset(state.ptr2 + pos, '\0', state.len[i]);
803
804 ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos);
805 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
806 }
807 }
808}
809
810TEST(string, memset) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400811 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400812 char ch = random () & 255;
813 for (size_t i = 0; i < state.n - 1; i++) {
814 for (size_t j = 0; j < POS_ITER; j++) {
815 state.NewIteration();
816
817 memset(state.ptr1, ~ch, state.MAX_LEN);
818 memcpy(state.ptr2, state.ptr1, state.MAX_LEN);
819
820 size_t pos = random () % (state.MAX_LEN - state.len[i]);
821 for (size_t k = pos; k < pos + state.len[i]; k++) {
822 state.ptr1[k] = ch;
823 }
824
825 ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos);
826
827 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
828 }
829 }
830}
831
832TEST(string, memmove) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400833 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400834 for (size_t i = 0; i < state.n - 1; i++) {
835 for (size_t j = 0; j < POS_ITER; j++) {
836 state.NewIteration();
837
838 memset(state.ptr1, random() & 255, 2 * state.MAX_LEN);
839
840 size_t pos = random() % (state.MAX_LEN - state.len[i]);
841
842 memset(state.ptr1, random() & 255, state.len[i]);
843 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
844 memcpy(state.ptr, state.ptr1, state.len[i]);
845 memcpy(state.ptr1 + pos, state.ptr, state.len[i]);
846
847 ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos);
848 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN));
849 }
850 }
851}
852
853TEST(string, bcopy) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400854 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400855 for (size_t i = 0; i < state.n; i++) {
856 for (size_t j = 0; j < POS_ITER; j++) {
857 state.NewIteration();
858
859 memset(state.ptr1, random() & 255, state.MAX_LEN);
860 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN);
861 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN);
862
863 size_t start = random() % (2 * state.MAX_LEN - state.len[i]);
864 memcpy(state.ptr2 + start, state.ptr1, state.len[i]);
865
866 bcopy(state.ptr1, state.ptr1 + start, state.len[i]);
867 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN));
868 }
869 }
870}
871
872TEST(string, bzero) {
Alexander Ivchenkobaa91f42013-06-27 12:55:46 +0400873 StringTestState<char> state(LARGE);
Anna Tikhonova036154b2012-10-05 15:21:11 +0400874 for (size_t j = 0; j < ITER; j++) {
875 state.NewIteration();
876
877 memset(state.ptr1, random() & 255, state.MAX_LEN);
878
879 size_t start = random() % state.MAX_LEN;
880 size_t end = start + random() % (state.MAX_LEN - start);
881
882 memcpy(state.ptr2, state.ptr1, start);
883 memset(state.ptr2 + start, '\0', end - start);
884 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end);
885
886 bzero(state.ptr1 + start, end - start);
887
888 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN));
889 }
890}
Christopher Ferrisb687ad32013-11-06 17:32:11 -0800891
892static void DoMemcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
893 memset(src, (len % 255) + 1, len);
894 memset(dst, 0, len);
895
896 ASSERT_EQ(dst, memcpy(dst, src, len));
897 ASSERT_TRUE(memcmp(src, dst, len) == 0);
898}
899
900TEST(string, memcpy_align) {
901 RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
902}
903
904TEST(string, memcpy_overread) {
905 RunSrcDstBufferOverreadTest(DoMemcpyTest);
906}
907
908static void DoMemsetTest(uint8_t* buf, size_t len) {
909 for (size_t i = 0; i < len; i++) {
910 buf[i] = 0;
911 }
912 int value = (len % 255) + 1;
913 ASSERT_EQ(buf, memset(buf, value, len));
914 for (size_t i = 0; i < len; i++) {
915 ASSERT_EQ(value, buf[i]);
916 }
917}
918
919TEST(string, memset_align) {
920 RunSingleBufferAlignTest(LARGE, DoMemsetTest);
921}
922
923static void DoStrlenTest(uint8_t* buf, size_t len) {
924 if (len >= 1) {
925 memset(buf, (32 + (len % 96)), len - 1);
926 buf[len-1] = '\0';
927 ASSERT_EQ(len-1, strlen(reinterpret_cast<char*>(buf)));
928 }
929}
930
931TEST(string, strlen_align) {
932 RunSingleBufferAlignTest(LARGE, DoStrlenTest);
933}
934
935TEST(string, strlen_overread) {
936 RunSingleBufferOverreadTest(DoStrlenTest);
937}
938
939static void DoStrcpyTest(uint8_t* src, uint8_t* dst, size_t len) {
940 if (len >= 1) {
941 memset(src, (32 + (len % 96)), len - 1);
942 src[len-1] = '\0';
943 memset(dst, 0, len);
944 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcpy(reinterpret_cast<char*>(dst),
945 reinterpret_cast<char*>(src))));
946 ASSERT_TRUE(memcmp(src, dst, len) == 0);
947 }
948}
949
950TEST(string, strcpy_align) {
951 RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
952}
953
954TEST(string, strcpy_overread) {
955 RunSrcDstBufferOverreadTest(DoStrcpyTest);
956}
957
958// Use our own incrementer to cut down on the total number of calls.
959static size_t StrcatSetIncrement(size_t len) {
960 if (len >= 4096) {
961 return 4096;
962 } else if (len >= 1024) {
963 return 1024;
964 } else if (len >= 256) {
965 return 256;
966 }
967 return 1;
968}
969
970#define STRCAT_DST_LEN 128
971
972static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) {
973 if (len >= 1) {
974 int value = 32 + (len % 96);
975 memset(src, value, len - 1);
976 src[len-1] = '\0';
977
978 if (len >= STRCAT_DST_LEN) {
979 // Create a small buffer for doing quick compares in each loop.
980 uint8_t cmp_buf[STRCAT_DST_LEN];
981 // Make sure dst string contains a different value then the src string.
982 int value2 = 32 + (value + 2) % 96;
983 memset(cmp_buf, value2, sizeof(cmp_buf));
984
985 for (size_t i = 1; i <= STRCAT_DST_LEN; i++) {
986 memset(dst, value2, i-1);
987 memset(dst+i-1, 0, len-i);
988 src[len-i] = '\0';
989 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
990 reinterpret_cast<char*>(src))));
991 ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
992 ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
993 }
994 } else {
995 dst[0] = '\0';
996 ASSERT_EQ(dst, reinterpret_cast<uint8_t*>(strcat(reinterpret_cast<char*>(dst),
997 reinterpret_cast<char*>(src))));
998 ASSERT_TRUE(memcmp(src, dst, len) == 0);
999 }
1000 }
1001}
1002
1003TEST(string, strcat_align) {
1004 RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, StrcatSetIncrement);
1005}
1006
1007TEST(string, strcat_overread) {
1008 RunSrcDstBufferOverreadTest(DoStrcatTest);
1009}