1 /*
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>
20 #include <malloc.h>
21 #include <math.h>
22 #include <string.h>
23
24 #include "buffer_tests.h"
25
26 #define KB 1024
27 #define SMALL 1*KB
28 #define MEDIUM 4*KB
29 #define LARGE 64*KB
30
signum(int i)31 static 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
TEST(string,strerror)40 TEST(string, strerror) {
41 // Valid.
42 ASSERT_STREQ("Success", strerror(0));
43 ASSERT_STREQ("Operation not permitted", strerror(1));
44
45 // Invalid.
46 ASSERT_STREQ("Unknown error -1", strerror(-1));
47 ASSERT_STREQ("Unknown error 1234", strerror(1234));
48 }
49
50 #if defined(__BIONIC__)
ConcurrentStrErrorFn(void *)51 static void* ConcurrentStrErrorFn(void*) {
52 bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
53 return reinterpret_cast<void*>(equal);
54 }
55 #endif // __BIONIC__
56
57 // glibc's strerror isn't thread safe, only its strsignal.
TEST(string,strerror_concurrent)58 TEST(string, strerror_concurrent) {
59 #if defined(__BIONIC__)
60 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);
70 #else // __BIONIC__
71 GTEST_LOG_(INFO) << "This test does nothing.\n";
72 #endif // __BIONIC__
73 }
74
TEST(string,strerror_r)75 TEST(string, strerror_r) {
76 #if defined(__BIONIC__) // glibc's strerror_r doesn't even have the same signature as the POSIX one.
77 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)));
87 ASSERT_STREQ("Unknown error -1", buf);
88 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);
94 #else // __BIONIC__
95 GTEST_LOG_(INFO) << "This test does nothing.\n";
96 #endif // __BIONIC__
97 }
98
TEST(string,strsignal)99 TEST(string, strsignal) {
100 // A regular signal.
101 ASSERT_STREQ("Hangup", strsignal(1));
102
103 // A real-time signal.
104 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));
107
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
ConcurrentStrSignalFn(void *)114 static void* ConcurrentStrSignalFn(void*) {
115 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
116 return reinterpret_cast<void*>(equal);
117 }
118
TEST(string,strsignal_concurrent)119 TEST(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 }
131
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.
141 template<class Character>
142 struct StringTestState {
StringTestStateStringTestState143 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".
147 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));
150
151 InitLenArray();
152
153 srandom(1234);
154 }
155
~StringTestStateStringTestState156 ~StringTestState() {
157 free(glob_ptr);
158 free(glob_ptr1);
159 free(glob_ptr2);
160 }
161
NewIterationStringTestState162 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;
174 Character *ptr, *ptr1, *ptr2;
175 size_t n;
176 int len[ITER + 1];
177
178 private:
179 Character *glob_ptr, *glob_ptr1, *glob_ptr2;
180
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.
InitLenArrayStringTestState185 void InitLenArray() {
186 n = 0;
187 len[n++] = 0;
188 for (size_t i = 1; i < ITER; ++i) {
189 int l = (int) exp(log((double) MAX_LEN) * i / ITER);
190 if (l != len[n - 1]) {
191 len[n++] = l;
192 }
193 }
194 len[n++] = MAX_LEN;
195 }
196 };
197
TEST(string,strcat)198 TEST(string, strcat) {
199 StringTestState<char> state(SMALL);
200 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
220 // one byte target with "\0" source
TEST(string,strcpy2)221 TEST(string, strcpy2) {
222 char buf[1];
223 char* orig = strdup("");
224 ASSERT_EQ(buf, strcpy(buf, orig));
225 ASSERT_EQ('\0', buf[0]);
226 free(orig);
227 }
228
229 // multibyte target where we under fill target
TEST(string,strcpy3)230 TEST(string, strcpy3) {
231 char buf[10];
232 char* orig = strdup("12345");
233 memset(buf, 'A', sizeof(buf));
234 ASSERT_EQ(buf, strcpy(buf, orig));
235 ASSERT_STREQ("12345", buf);
236 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
TEST(string,strcpy4)244 TEST(string, strcpy4) {
245 char buf[10];
246 char* orig = strdup("123456789");
247 memset(buf, 'A', sizeof(buf));
248 ASSERT_EQ(buf, strcpy(buf, orig));
249 ASSERT_STREQ("123456789", buf);
250 free(orig);
251 }
252
253 // one byte target with "\0" source
TEST(string,stpcpy2)254 TEST(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
TEST(string,stpcpy3)263 TEST(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
TEST(string,stpcpy4)277 TEST(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);
283 free(orig);
284 }
285
TEST(string,strcat2)286 TEST(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);
293 ASSERT_STREQ("a01234", buf);
294 ASSERT_EQ('A', buf[7]);
295 ASSERT_EQ('A', buf[8]);
296 ASSERT_EQ('A', buf[9]);
297 }
298
TEST(string,strcat3)299 TEST(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);
306 ASSERT_STREQ("a01234567", buf);
307 }
308
TEST(string,strncat2)309 TEST(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);
316 ASSERT_STREQ("a01234", buf);
317 ASSERT_EQ('A', buf[7]);
318 ASSERT_EQ('A', buf[8]);
319 ASSERT_EQ('A', buf[9]);
320 }
321
TEST(string,strncat3)322 TEST(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);
329 ASSERT_STREQ("a01234", buf);
330 ASSERT_EQ('A', buf[7]);
331 ASSERT_EQ('A', buf[8]);
332 ASSERT_EQ('A', buf[9]);
333 }
334
TEST(string,strncat4)335 TEST(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);
342 ASSERT_STREQ("a01234567", buf);
343 }
344
TEST(string,strncat5)345 TEST(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);
352 ASSERT_STREQ("a01234567", buf);
353 }
354
TEST(string,strchr_with_0)355 TEST(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
TEST(string,strchr_multiple)362 TEST(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
TEST(string,strchr)380 TEST(string, strchr) {
381 int seek_char = random() & 255;
382
383 StringTestState<char> state(SMALL);
384 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
395 int pos = random() % state.MAX_LEN;
396 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
TEST(string,strcmp)413 TEST(string, strcmp) {
414 StringTestState<char> state(SMALL);
415 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
424 int pos = 1 + (random() % (state.MAX_LEN - 1));
425 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
TEST(string,stpcpy)450 TEST(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
TEST(string,strcpy)476 TEST(string, strcpy) {
477 StringTestState<char> state(SMALL);
478 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
TEST(string,strlcat)502 TEST(string, strlcat) {
503 #if defined(__BIONIC__)
504 StringTestState<char> state(SMALL);
505 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
513 int pos = random() % state.MAX_LEN;
514 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 }
528 #else // __BIONIC__
529 GTEST_LOG_(INFO) << "This test does nothing.\n";
530 #endif // __BIONIC__
531 }
532
TEST(string,strlcpy)533 TEST(string, strlcpy) {
534 #if defined(__BIONIC__)
535 StringTestState<char> state(SMALL);
536 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 }
565 #else // __BIONIC__
566 GTEST_LOG_(INFO) << "This test does nothing.\n";
567 #endif // __BIONIC__
568 }
569
TEST(string,strncat)570 TEST(string, strncat) {
571 StringTestState<char> state(SMALL);
572 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
TEST(string,strncmp)596 TEST(string, strncmp) {
597 StringTestState<char> state(SMALL);
598 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
607 int pos = 1 + (random() % (state.MAX_LEN - 1));
608 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
TEST(string,stpncpy)633 TEST(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
TEST(string,strncpy)672 TEST(string, strncpy) {
673 StringTestState<char> state(SMALL);
674 for (size_t j = 0; j < ITER; j++) {
675 state.NewIteration();
676
677 // 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.
684 memcpy(state.ptr, state.ptr1, state.MAX_LEN);
685 // Init ptr2 to a set value.
686 memset(state.ptr2, '\1', state.MAX_LEN);
687
688 // 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;
698 } else {
699 expected_end = copy_len;
700 }
701
702 ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
703
704 // 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));
708 }
709 }
710
TEST(string,strrchr)711 TEST(string, strrchr) {
712 int seek_char = random() & 255;
713 StringTestState<char> state(SMALL);
714 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
725 int pos = random() % state.MAX_LEN;
726 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
TEST(string,memchr)743 TEST(string, memchr) {
744 int seek_char = random() & 255;
745 StringTestState<char> state(SMALL);
746 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
752 int pos = random() % state.MAX_LEN;
753 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
TEST(string,memchr_zero)766 TEST(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
TEST(string,memrchr)774 TEST(string, memrchr) {
775 int seek_char = random() & 255;
776 StringTestState<char> state(SMALL);
777 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
783 int pos = random() % state.MAX_LEN;
784 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
TEST(string,memcmp)797 TEST(string, memcmp) {
798 StringTestState<char> state(SMALL);
799 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
TEST(string,wmemcmp)819 TEST(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
TEST(string,memcpy)843 TEST(string, memcpy) {
844 StringTestState<char> state(LARGE);
845 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
TEST(string,memset)865 TEST(string, memset) {
866 StringTestState<char> state(LARGE);
867 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
TEST(string,memmove)887 TEST(string, memmove) {
888 StringTestState<char> state(LARGE);
889 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
TEST(string,memmove_cache_size)908 TEST(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
verify_memmove(char * src_copy,char * dst,char * src,size_t size)937 static 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
TEST(string,memmove_check)946 TEST(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
TEST(string,bcopy)987 TEST(string, bcopy) {
988 StringTestState<char> state(LARGE);
989 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
TEST(string,bzero)1006 TEST(string, bzero) {
1007 StringTestState<char> state(LARGE);
1008 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 }
1025
DoMemcpyTest(uint8_t * src,uint8_t * dst,size_t len)1026 static 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
TEST(string,memcpy_align)1034 TEST(string, memcpy_align) {
1035 RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
1036 }
1037
TEST(string,memcpy_overread)1038 TEST(string, memcpy_overread) {
1039 RunSrcDstBufferOverreadTest(DoMemcpyTest);
1040 }
1041
DoMemmoveTest(uint8_t * src,uint8_t * dst,size_t len)1042 static 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
TEST(string,memmove_align)1050 TEST(string, memmove_align) {
1051 RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
1052 }
1053
TEST(string,memmove_overread)1054 TEST(string, memmove_overread) {
1055 RunSrcDstBufferOverreadTest(DoMemmoveTest);
1056 }
1057
DoMemsetTest(uint8_t * buf,size_t len)1058 static 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
TEST(string,memset_align)1069 TEST(string, memset_align) {
1070 RunSingleBufferAlignTest(LARGE, DoMemsetTest);
1071 }
1072
DoStrlenTest(uint8_t * buf,size_t len)1073 static 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
TEST(string,strlen_align)1081 TEST(string, strlen_align) {
1082 RunSingleBufferAlignTest(LARGE, DoStrlenTest);
1083 }
1084
TEST(string,strlen_overread)1085 TEST(string, strlen_overread) {
1086 RunSingleBufferOverreadTest(DoStrlenTest);
1087 }
1088
DoStrcpyTest(uint8_t * src,uint8_t * dst,size_t len)1089 static 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
TEST(string,strcpy_align)1100 TEST(string, strcpy_align) {
1101 RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
1102 }
1103
TEST(string,strcpy_overread)1104 TEST(string, strcpy_overread) {
1105 RunSrcDstBufferOverreadTest(DoStrcpyTest);
1106 }
1107
DoStpcpyTest(uint8_t * src,uint8_t * dst,size_t len)1108 static 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
TEST(string,stpcpy_align)1119 TEST(string, stpcpy_align) {
1120 RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest);
1121 }
1122
TEST(string,stpcpy_overread)1123 TEST(string, stpcpy_overread) {
1124 RunSrcDstBufferOverreadTest(DoStpcpyTest);
1125 }
1126
1127 // Use our own incrementer to cut down on the total number of calls.
LargeSetIncrement(size_t len)1128 static size_t LargeSetIncrement(size_t len) {
1129 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
DoStrcatTest(uint8_t * src,uint8_t * dst,size_t len)1141 static 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
TEST(string,strcat_align)1172 TEST(string, strcat_align) {
1173 RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement);
1174 }
1175
TEST(string,strcat_overread)1176 TEST(string, strcat_overread) {
1177 RunSrcDstBufferOverreadTest(DoStrcatTest);
1178 }
1179
DoStrcmpTest(uint8_t * buf1,uint8_t * buf2,size_t len)1180 static 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
DoStrcmpFailTest(uint8_t * buf1,uint8_t * buf2,size_t len1,size_t len2)1191 static 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
TEST(string,strcmp_align)1225 TEST(string, strcmp_align) {
1226 RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement);
1227 }
1228
TEST(string,strcmp_overread)1229 TEST(string, strcmp_overread) {
1230 RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest);
1231 }
1232
DoMemcmpTest(uint8_t * buf1,uint8_t * buf2,size_t len)1233 static 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
DoMemcmpFailTest(uint8_t * buf1,uint8_t * buf2,size_t len1,size_t len2)1239 static 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
TEST(string,memcmp_align)1257 TEST(string, memcmp_align) {
1258 RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement);
1259 }
1260
TEST(string,memcmp_overread)1261 TEST(string, memcmp_overread) {
1262 RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
1263 }
1264
DoStrchrTest(uint8_t * buf,size_t len)1265 static 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
TEST(string,strchr_align)1283 TEST(string, strchr_align) {
1284 RunSingleBufferAlignTest(MEDIUM, DoStrchrTest);
1285 }
1286
TEST(string,strchr_overread)1287 TEST(string, strchr_overread) {
1288 RunSingleBufferOverreadTest(DoStrchrTest);
1289 }
1290