]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/netbsd-tests/lib/libc/string/t_strlen.c
MFC r314450,r313439:
[FreeBSD/stable/10.git] / contrib / netbsd-tests / lib / libc / string / t_strlen.c
1 /* $NetBSD: t_strlen.c,v 1.6 2017/01/14 20:49:24 christos Exp $ */
2
3 /*
4  * Written by J.T. Conklin <jtc@acorntoolworks.com>
5  * Public domain.
6  */
7
8 #include <atf-c.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <dlfcn.h>
14 #include <unistd.h>
15
16 static void     write_num(int);
17
18 static void
19 write_num(int val)
20 {
21         char buf[20];
22         int i;
23
24         for (i = sizeof buf; --i >= 0;) {
25                 buf[i] = '0' + val % 10;
26                 val /= 10;
27                 if (val == 0) {
28                         write(2, buf + i, sizeof buf - i);
29                         return;
30                 }
31         }
32         write(2, "overflow", 8);
33 }
34
35 ATF_TC(strlen_basic);
36 ATF_TC_HEAD(strlen_basic, tc)
37 {
38         atf_tc_set_md_var(tc, "descr", "Test strlen(3) results");
39 }
40
41 ATF_TC_BODY(strlen_basic, tc)
42 {
43         void *dl_handle;
44         /* try to trick the compiler */
45         size_t (*strlen_fn)(const char *);
46
47         unsigned int a, t;
48         size_t len;
49         char buf[64];
50
51         struct tab {
52                 const char*     val;
53                 size_t          len;
54         };
55
56         const struct tab tab[] = {
57                 /*
58                  * patterns that check for all combinations of leading and
59                  * trailing unaligned characters (on a 64 bit processor)
60                  */
61
62                 { "",                           0 },
63                 { "a",                          1 },
64                 { "ab",                         2 },
65                 { "abc",                        3 },
66                 { "abcd",                       4 },
67                 { "abcde",                      5 },
68                 { "abcdef",                     6 },
69                 { "abcdefg",                    7 },
70                 { "abcdefgh",                   8 },
71                 { "abcdefghi",                  9 },
72                 { "abcdefghij",                 10 },
73                 { "abcdefghijk",                11 },
74                 { "abcdefghijkl",               12 },
75                 { "abcdefghijklm",              13 },
76                 { "abcdefghijklmn",             14 },
77                 { "abcdefghijklmno",            15 },
78                 { "abcdefghijklmnop",           16 },
79                 { "abcdefghijklmnopq",          17 },
80                 { "abcdefghijklmnopqr",         18 },
81                 { "abcdefghijklmnopqrs",        19 },
82                 { "abcdefghijklmnopqrst",       20 },
83                 { "abcdefghijklmnopqrstu",      21 },
84                 { "abcdefghijklmnopqrstuv",     22 },
85                 { "abcdefghijklmnopqrstuvw",    23 },
86
87                 /*
88                  * patterns that check for the cases where the expression:
89                  *
90                  *      ((word - 0x7f7f..7f) & 0x8080..80)
91                  *
92                  * returns non-zero even though there are no zero bytes in
93                  * the word.
94                  */
95
96                 { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh",     16 },
97                 { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh",     16 },
98                 { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh",     16 },
99                 { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh",     16 },
100                 { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh",     16 },
101                 { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh",     16 },
102                 { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh",     16 },
103                 { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h",     16 },
104                 { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "",     16 },
105         };
106
107         /*
108          * During testing it is useful have the rest of the program
109          * use a known good version!
110          */
111         dl_handle = dlopen(NULL, RTLD_LAZY);
112         strlen_fn = dlsym(dl_handle, "test_strlen");
113         if (!strlen_fn)
114                 strlen_fn = strlen;
115
116         for (a = 0; a < sizeof(long); ++a) {
117                 for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
118
119                         memcpy(&buf[a], tab[t].val, tab[t].len + 1);
120                         len = strlen_fn(&buf[a]);
121
122                         if (len != tab[t].len) {
123                                 /* Write error without using printf / strlen */
124                                 write(2, "alignment ", 10);
125                                 write_num(a);
126                                 write(2, ", test ", 7);
127                                 write_num(t);
128                                 write(2, ", got len ", 10);
129                                 write_num(len);
130                                 write(2, ", not ", 6);
131                                 write_num(tab[t].len);
132                                 write(2, ", for '", 7);
133                                 write(2, tab[t].val, tab[t].len);
134                                 write(2, "'\n", 2);
135                                 atf_tc_fail("See stderr for details");
136                         }
137                 }
138         }
139         (void)dlclose(dl_handle);
140 }
141
142 ATF_TC(strlen_huge);
143 ATF_TC_HEAD(strlen_huge, tc)
144 {
145         atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings");
146 }
147
148 ATF_TC_BODY(strlen_huge, tc)
149 {
150         long page;
151         char *str;
152         size_t i;
153
154         page = sysconf(_SC_PAGESIZE);
155         ATF_REQUIRE(page >= 0);
156
157         for (i = 1; i < 1000; i = i + 100) {
158
159                 str = malloc(i * page + 1);
160
161                 if (str == NULL)
162                         continue;
163
164                 (void)memset(str, 'x', i * page);
165                 str[i * page] = '\0';
166
167                 ATF_REQUIRE(strlen(str) == i * page);
168                 free(str);
169         }
170 }
171
172 ATF_TC(strnlen_basic);
173 ATF_TC_HEAD(strnlen_basic, tc)
174 {
175         atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)");
176 }
177
178 ATF_TC_BODY(strnlen_basic, tc)
179 {
180         char buf[1];
181
182         buf[0] = '\0';
183
184         ATF_CHECK(strnlen(buf, 000) == 0);
185         ATF_CHECK(strnlen(buf, 111) == 0);
186
187         ATF_CHECK(strnlen("xxx", 0) == 0);
188         ATF_CHECK(strnlen("xxx", 1) == 1);
189         ATF_CHECK(strnlen("xxx", 2) == 2);
190         ATF_CHECK(strnlen("xxx", 3) == 3);
191         ATF_CHECK(strnlen("xxx", 9) == 3);
192 }
193
194 ATF_TP_ADD_TCS(tp)
195 {
196
197         ATF_TP_ADD_TC(tp, strlen_basic);
198         ATF_TP_ADD_TC(tp, strlen_huge);
199         ATF_TP_ADD_TC(tp, strnlen_basic);
200
201         return atf_no_error();
202 }