t_strchrnul.c revision 1.1 1 1.1 christos /* $NetBSD: t_strchrnul.c,v 1.1 2023/01/30 19:49:49 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Written by J.T. Conklin <jtc (at) acorntoolworks.com>
5 1.1 christos * Public domain.
6 1.1 christos */
7 1.1 christos
8 1.1 christos #include <atf-c.h>
9 1.1 christos #include <string.h>
10 1.1 christos #include <unistd.h>
11 1.1 christos #include <stdio.h>
12 1.1 christos #include <stdlib.h>
13 1.1 christos #include <dlfcn.h>
14 1.1 christos
15 1.1 christos static char *slow_strchrnul(char *, int);
16 1.1 christos static void verify_strchrnul(char *, int, unsigned int, unsigned int);
17 1.1 christos
18 1.1 christos char * (*volatile strchrnul_fn)(const char *, int);
19 1.1 christos
20 1.1 christos static char *
21 1.1 christos slow_strchrnul(char *buf, int ch)
22 1.1 christos {
23 1.1 christos unsigned char c = 1;
24 1.1 christos
25 1.1 christos ch &= 0xff;
26 1.1 christos
27 1.1 christos for (; ; buf++) {
28 1.1 christos c = *buf;
29 1.1 christos if (c == ch || c == 0)
30 1.1 christos return buf;
31 1.1 christos }
32 1.1 christos }
33 1.1 christos
34 1.1 christos static void
35 1.1 christos verify_strchrnul(char *buf, int ch, unsigned int t, unsigned int a)
36 1.1 christos {
37 1.1 christos const char *off, *ok_off;
38 1.1 christos
39 1.1 christos off = strchrnul_fn(buf, ch);
40 1.1 christos ok_off = slow_strchrnul(buf, ch);
41 1.1 christos if (off == ok_off)
42 1.1 christos return;
43 1.1 christos
44 1.1 christos fprintf(stderr, "test_strchrnul(\"%s\", %#x) gave %zd not %zd (test %d, "
45 1.1 christos "alignment %d)\n",
46 1.1 christos buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a);
47 1.1 christos
48 1.1 christos atf_tc_fail("Check stderr for details");
49 1.1 christos }
50 1.1 christos
51 1.1 christos ATF_TC(strchrnul_basic);
52 1.1 christos ATF_TC_HEAD(strchrnul_basic, tc)
53 1.1 christos {
54 1.1 christos
55 1.1 christos atf_tc_set_md_var(tc, "descr", "Test strchrnul(3) results");
56 1.1 christos }
57 1.1 christos
58 1.1 christos ATF_TC_BODY(strchrnul_basic, tc)
59 1.1 christos {
60 1.1 christos void *dl_handle;
61 1.1 christos char *off;
62 1.1 christos char buf[32];
63 1.1 christos unsigned int t, a;
64 1.1 christos
65 1.1 christos const char *tab[] = {
66 1.1 christos "",
67 1.1 christos "a",
68 1.1 christos "aa",
69 1.1 christos "abc",
70 1.1 christos "abcd",
71 1.1 christos "abcde",
72 1.1 christos "abcdef",
73 1.1 christos "abcdefg",
74 1.1 christos "abcdefgh",
75 1.1 christos
76 1.1 christos "/",
77 1.1 christos "//",
78 1.1 christos "/a",
79 1.1 christos "/a/",
80 1.1 christos "/ab",
81 1.1 christos "/ab/",
82 1.1 christos "/abc",
83 1.1 christos "/abc/",
84 1.1 christos "/abcd",
85 1.1 christos "/abcd/",
86 1.1 christos "/abcde",
87 1.1 christos "/abcde/",
88 1.1 christos "/abcdef",
89 1.1 christos "/abcdef/",
90 1.1 christos "/abcdefg",
91 1.1 christos "/abcdefg/",
92 1.1 christos "/abcdefgh",
93 1.1 christos "/abcdefgh/",
94 1.1 christos
95 1.1 christos "a/",
96 1.1 christos "a//",
97 1.1 christos "a/a",
98 1.1 christos "a/a/",
99 1.1 christos "a/ab",
100 1.1 christos "a/ab/",
101 1.1 christos "a/abc",
102 1.1 christos "a/abc/",
103 1.1 christos "a/abcd",
104 1.1 christos "a/abcd/",
105 1.1 christos "a/abcde",
106 1.1 christos "a/abcde/",
107 1.1 christos "a/abcdef",
108 1.1 christos "a/abcdef/",
109 1.1 christos "a/abcdefg",
110 1.1 christos "a/abcdefg/",
111 1.1 christos "a/abcdefgh",
112 1.1 christos "a/abcdefgh/",
113 1.1 christos
114 1.1 christos "ab/",
115 1.1 christos "ab//",
116 1.1 christos "ab/a",
117 1.1 christos "ab/a/",
118 1.1 christos "ab/ab",
119 1.1 christos "ab/ab/",
120 1.1 christos "ab/abc",
121 1.1 christos "ab/abc/",
122 1.1 christos "ab/abcd",
123 1.1 christos "ab/abcd/",
124 1.1 christos "ab/abcde",
125 1.1 christos "ab/abcde/",
126 1.1 christos "ab/abcdef",
127 1.1 christos "ab/abcdef/",
128 1.1 christos "ab/abcdefg",
129 1.1 christos "ab/abcdefg/",
130 1.1 christos "ab/abcdefgh",
131 1.1 christos "ab/abcdefgh/",
132 1.1 christos
133 1.1 christos "abc/",
134 1.1 christos "abc//",
135 1.1 christos "abc/a",
136 1.1 christos "abc/a/",
137 1.1 christos "abc/ab",
138 1.1 christos "abc/ab/",
139 1.1 christos "abc/abc",
140 1.1 christos "abc/abc/",
141 1.1 christos "abc/abcd",
142 1.1 christos "abc/abcd/",
143 1.1 christos "abc/abcde",
144 1.1 christos "abc/abcde/",
145 1.1 christos "abc/abcdef",
146 1.1 christos "abc/abcdef/",
147 1.1 christos "abc/abcdefg",
148 1.1 christos "abc/abcdefg/",
149 1.1 christos "abc/abcdefgh",
150 1.1 christos "abc/abcdefgh/",
151 1.1 christos
152 1.1 christos "abcd/",
153 1.1 christos "abcd//",
154 1.1 christos "abcd/a",
155 1.1 christos "abcd/a/",
156 1.1 christos "abcd/ab",
157 1.1 christos "abcd/ab/",
158 1.1 christos "abcd/abc",
159 1.1 christos "abcd/abc/",
160 1.1 christos "abcd/abcd",
161 1.1 christos "abcd/abcd/",
162 1.1 christos "abcd/abcde",
163 1.1 christos "abcd/abcde/",
164 1.1 christos "abcd/abcdef",
165 1.1 christos "abcd/abcdef/",
166 1.1 christos "abcd/abcdefg",
167 1.1 christos "abcd/abcdefg/",
168 1.1 christos "abcd/abcdefgh",
169 1.1 christos "abcd/abcdefgh/",
170 1.1 christos
171 1.1 christos "abcde/",
172 1.1 christos "abcde//",
173 1.1 christos "abcde/a",
174 1.1 christos "abcde/a/",
175 1.1 christos "abcde/ab",
176 1.1 christos "abcde/ab/",
177 1.1 christos "abcde/abc",
178 1.1 christos "abcde/abc/",
179 1.1 christos "abcde/abcd",
180 1.1 christos "abcde/abcd/",
181 1.1 christos "abcde/abcde",
182 1.1 christos "abcde/abcde/",
183 1.1 christos "abcde/abcdef",
184 1.1 christos "abcde/abcdef/",
185 1.1 christos "abcde/abcdefg",
186 1.1 christos "abcde/abcdefg/",
187 1.1 christos "abcde/abcdefgh",
188 1.1 christos "abcde/abcdefgh/",
189 1.1 christos
190 1.1 christos "abcdef/",
191 1.1 christos "abcdef//",
192 1.1 christos "abcdef/a",
193 1.1 christos "abcdef/a/",
194 1.1 christos "abcdef/ab",
195 1.1 christos "abcdef/ab/",
196 1.1 christos "abcdef/abc",
197 1.1 christos "abcdef/abc/",
198 1.1 christos "abcdef/abcd",
199 1.1 christos "abcdef/abcd/",
200 1.1 christos "abcdef/abcde",
201 1.1 christos "abcdef/abcde/",
202 1.1 christos "abcdef/abcdef",
203 1.1 christos "abcdef/abcdef/",
204 1.1 christos "abcdef/abcdefg",
205 1.1 christos "abcdef/abcdefg/",
206 1.1 christos "abcdef/abcdefgh",
207 1.1 christos "abcdef/abcdefgh/",
208 1.1 christos
209 1.1 christos "abcdefg/",
210 1.1 christos "abcdefg//",
211 1.1 christos "abcdefg/a",
212 1.1 christos "abcdefg/a/",
213 1.1 christos "abcdefg/ab",
214 1.1 christos "abcdefg/ab/",
215 1.1 christos "abcdefg/abc",
216 1.1 christos "abcdefg/abc/",
217 1.1 christos "abcdefg/abcd",
218 1.1 christos "abcdefg/abcd/",
219 1.1 christos "abcdefg/abcde",
220 1.1 christos "abcdefg/abcde/",
221 1.1 christos "abcdefg/abcdef",
222 1.1 christos "abcdefg/abcdef/",
223 1.1 christos "abcdefg/abcdefg",
224 1.1 christos "abcdefg/abcdefg/",
225 1.1 christos "abcdefg/abcdefgh",
226 1.1 christos "abcdefg/abcdefgh/",
227 1.1 christos
228 1.1 christos "abcdefgh/",
229 1.1 christos "abcdefgh//",
230 1.1 christos "abcdefgh/a",
231 1.1 christos "abcdefgh/a/",
232 1.1 christos "abcdefgh/ab",
233 1.1 christos "abcdefgh/ab/",
234 1.1 christos "abcdefgh/abc",
235 1.1 christos "abcdefgh/abc/",
236 1.1 christos "abcdefgh/abcd",
237 1.1 christos "abcdefgh/abcd/",
238 1.1 christos "abcdefgh/abcde",
239 1.1 christos "abcdefgh/abcde/",
240 1.1 christos "abcdefgh/abcdef",
241 1.1 christos "abcdefgh/abcdef/",
242 1.1 christos "abcdefgh/abcdefg",
243 1.1 christos "abcdefgh/abcdefg/",
244 1.1 christos "abcdefgh/abcdefgh",
245 1.1 christos "abcdefgh/abcdefgh/",
246 1.1 christos };
247 1.1 christos
248 1.1 christos dl_handle = dlopen(NULL, RTLD_LAZY);
249 1.1 christos strchrnul_fn = dlsym(dl_handle, "test_strchrnul");
250 1.1 christos if (!strchrnul_fn)
251 1.1 christos strchrnul_fn = strchrnul;
252 1.1 christos
253 1.1 christos for (a = 3; a < 3 + sizeof(long); ++a) {
254 1.1 christos /* Put char and a \0 before the buffer */
255 1.1 christos buf[a-1] = '/';
256 1.1 christos buf[a-2] = '0';
257 1.1 christos buf[a-3] = 0xff;
258 1.1 christos for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
259 1.1 christos int len = strlen(tab[t]) + 1;
260 1.1 christos memcpy(&buf[a], tab[t], len);
261 1.1 christos
262 1.1 christos /* Put the char we are looking for after the \0 */
263 1.1 christos buf[a + len] = '/';
264 1.1 christos
265 1.1 christos /* Check search for NUL at end of string */
266 1.1 christos verify_strchrnul(buf + a, 0, t, a);
267 1.1 christos
268 1.1 christos /* Then for the '/' in the strings */
269 1.1 christos verify_strchrnul(buf + a, '/', t, a);
270 1.1 christos
271 1.1 christos /* check zero extension of char arg */
272 1.1 christos verify_strchrnul(buf + a, 0xffffff00 | '/', t, a);
273 1.1 christos
274 1.1 christos /* Replace all the '/' with 0xff */
275 1.1 christos while (*(off = slow_strchrnul(buf + a, '/')) != '\0')
276 1.1 christos *off = 0xff;
277 1.1 christos
278 1.1 christos buf[a + len] = 0xff;
279 1.1 christos
280 1.1 christos /* Check we can search for 0xff as well as '/' */
281 1.1 christos verify_strchrnul(buf + a, 0xff, t, a);
282 1.1 christos }
283 1.1 christos }
284 1.1 christos (void)dlclose(dl_handle);
285 1.1 christos }
286 1.1 christos
287 1.1 christos ATF_TP_ADD_TCS(tp)
288 1.1 christos {
289 1.1 christos
290 1.1 christos ATF_TP_ADD_TC(tp, strchrnul_basic);
291 1.1 christos
292 1.1 christos return atf_no_error();
293 1.1 christos }
294