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