xref: /netbsd-src/tests/lib/libc/string/t_strchr.c (revision e20f737644f47900246981f10cc4584e92e67bc3)
1*e20f7376Schristos /* $NetBSD: t_strchr.c,v 1.3 2023/01/30 19:49:49 christos Exp $ */
254bb1074Sjruoho 
354bb1074Sjruoho /*
454bb1074Sjruoho  * Written by J.T. Conklin <jtc@acorntoolworks.com>
554bb1074Sjruoho  * Public domain.
654bb1074Sjruoho  */
754bb1074Sjruoho 
854bb1074Sjruoho #include <atf-c.h>
954bb1074Sjruoho #include <string.h>
1054bb1074Sjruoho #include <unistd.h>
1154bb1074Sjruoho #include <stdio.h>
1254bb1074Sjruoho #include <stdlib.h>
1354bb1074Sjruoho #include <dlfcn.h>
1454bb1074Sjruoho 
1554bb1074Sjruoho static char	*slow_strchr(char *, int);
1654bb1074Sjruoho static void	 verify_strchr(char *, int, unsigned int, unsigned int);
1754bb1074Sjruoho 
1854bb1074Sjruoho char * (*volatile strchr_fn)(const char *, int);
1954bb1074Sjruoho 
2054bb1074Sjruoho static char *
slow_strchr(char * buf,int ch)2154bb1074Sjruoho slow_strchr(char *buf, int ch)
2254bb1074Sjruoho {
2354bb1074Sjruoho 	unsigned char c = 1;
2454bb1074Sjruoho 
2554bb1074Sjruoho 	ch &= 0xff;
2654bb1074Sjruoho 
2754bb1074Sjruoho 	for (; c != 0; buf++) {
2854bb1074Sjruoho 		c = *buf;
2954bb1074Sjruoho 		if (c == ch)
3054bb1074Sjruoho 			return buf;
3154bb1074Sjruoho 	}
3254bb1074Sjruoho 	return 0;
3354bb1074Sjruoho }
3454bb1074Sjruoho 
3554bb1074Sjruoho static void
verify_strchr(char * buf,int ch,unsigned int t,unsigned int a)3654bb1074Sjruoho verify_strchr(char *buf, int ch, unsigned int t, unsigned int a)
3754bb1074Sjruoho {
3854bb1074Sjruoho 	const char *off, *ok_off;
3954bb1074Sjruoho 
4054bb1074Sjruoho 	off = strchr_fn(buf, ch);
4154bb1074Sjruoho 	ok_off = slow_strchr(buf, ch);
4254bb1074Sjruoho 	if (off == ok_off)
4354bb1074Sjruoho 		return;
4454bb1074Sjruoho 
4554bb1074Sjruoho 	fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, "
4654bb1074Sjruoho 	    "alignment %d)\n",
4754bb1074Sjruoho 	    buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a);
4854bb1074Sjruoho 
4954bb1074Sjruoho 	atf_tc_fail("Check stderr for details");
5054bb1074Sjruoho }
5154bb1074Sjruoho 
5254bb1074Sjruoho ATF_TC(strchr_basic);
ATF_TC_HEAD(strchr_basic,tc)5354bb1074Sjruoho ATF_TC_HEAD(strchr_basic, tc)
5454bb1074Sjruoho {
5554bb1074Sjruoho 
5654bb1074Sjruoho         atf_tc_set_md_var(tc, "descr", "Test strchr(3) results");
5754bb1074Sjruoho }
5854bb1074Sjruoho 
ATF_TC_BODY(strchr_basic,tc)5954bb1074Sjruoho ATF_TC_BODY(strchr_basic, tc)
6054bb1074Sjruoho {
610480186dSchristos 	void *dl_handle;
6254bb1074Sjruoho 	char *off;
6354bb1074Sjruoho 	char buf[32];
640480186dSchristos 	unsigned int t, a;
6554bb1074Sjruoho 
6654bb1074Sjruoho 	const char *tab[] = {
6754bb1074Sjruoho 		"",
6854bb1074Sjruoho 		"a",
6954bb1074Sjruoho 		"aa",
7054bb1074Sjruoho 		"abc",
7154bb1074Sjruoho 		"abcd",
7254bb1074Sjruoho 		"abcde",
7354bb1074Sjruoho 		"abcdef",
7454bb1074Sjruoho 		"abcdefg",
7554bb1074Sjruoho 		"abcdefgh",
7654bb1074Sjruoho 
7754bb1074Sjruoho 		"/",
7854bb1074Sjruoho 		"//",
7954bb1074Sjruoho 		"/a",
8054bb1074Sjruoho 		"/a/",
8154bb1074Sjruoho 		"/ab",
8254bb1074Sjruoho 		"/ab/",
8354bb1074Sjruoho 		"/abc",
8454bb1074Sjruoho 		"/abc/",
8554bb1074Sjruoho 		"/abcd",
8654bb1074Sjruoho 		"/abcd/",
8754bb1074Sjruoho 		"/abcde",
8854bb1074Sjruoho 		"/abcde/",
8954bb1074Sjruoho 		"/abcdef",
9054bb1074Sjruoho 		"/abcdef/",
9154bb1074Sjruoho 		"/abcdefg",
9254bb1074Sjruoho 		"/abcdefg/",
9354bb1074Sjruoho 		"/abcdefgh",
9454bb1074Sjruoho 		"/abcdefgh/",
9554bb1074Sjruoho 
9654bb1074Sjruoho 		"a/",
9754bb1074Sjruoho 		"a//",
9854bb1074Sjruoho 		"a/a",
9954bb1074Sjruoho 		"a/a/",
10054bb1074Sjruoho 		"a/ab",
10154bb1074Sjruoho 		"a/ab/",
10254bb1074Sjruoho 		"a/abc",
10354bb1074Sjruoho 		"a/abc/",
10454bb1074Sjruoho 		"a/abcd",
10554bb1074Sjruoho 		"a/abcd/",
10654bb1074Sjruoho 		"a/abcde",
10754bb1074Sjruoho 		"a/abcde/",
10854bb1074Sjruoho 		"a/abcdef",
10954bb1074Sjruoho 		"a/abcdef/",
11054bb1074Sjruoho 		"a/abcdefg",
11154bb1074Sjruoho 		"a/abcdefg/",
11254bb1074Sjruoho 		"a/abcdefgh",
11354bb1074Sjruoho 		"a/abcdefgh/",
11454bb1074Sjruoho 
11554bb1074Sjruoho 		"ab/",
11654bb1074Sjruoho 		"ab//",
11754bb1074Sjruoho 		"ab/a",
11854bb1074Sjruoho 		"ab/a/",
11954bb1074Sjruoho 		"ab/ab",
12054bb1074Sjruoho 		"ab/ab/",
12154bb1074Sjruoho 		"ab/abc",
12254bb1074Sjruoho 		"ab/abc/",
12354bb1074Sjruoho 		"ab/abcd",
12454bb1074Sjruoho 		"ab/abcd/",
12554bb1074Sjruoho 		"ab/abcde",
12654bb1074Sjruoho 		"ab/abcde/",
12754bb1074Sjruoho 		"ab/abcdef",
12854bb1074Sjruoho 		"ab/abcdef/",
12954bb1074Sjruoho 		"ab/abcdefg",
13054bb1074Sjruoho 		"ab/abcdefg/",
13154bb1074Sjruoho 		"ab/abcdefgh",
13254bb1074Sjruoho 		"ab/abcdefgh/",
13354bb1074Sjruoho 
13454bb1074Sjruoho 		"abc/",
13554bb1074Sjruoho 		"abc//",
13654bb1074Sjruoho 		"abc/a",
13754bb1074Sjruoho 		"abc/a/",
13854bb1074Sjruoho 		"abc/ab",
13954bb1074Sjruoho 		"abc/ab/",
14054bb1074Sjruoho 		"abc/abc",
14154bb1074Sjruoho 		"abc/abc/",
14254bb1074Sjruoho 		"abc/abcd",
14354bb1074Sjruoho 		"abc/abcd/",
14454bb1074Sjruoho 		"abc/abcde",
14554bb1074Sjruoho 		"abc/abcde/",
14654bb1074Sjruoho 		"abc/abcdef",
14754bb1074Sjruoho 		"abc/abcdef/",
14854bb1074Sjruoho 		"abc/abcdefg",
14954bb1074Sjruoho 		"abc/abcdefg/",
15054bb1074Sjruoho 		"abc/abcdefgh",
15154bb1074Sjruoho 		"abc/abcdefgh/",
15254bb1074Sjruoho 
15354bb1074Sjruoho 		"abcd/",
15454bb1074Sjruoho 		"abcd//",
15554bb1074Sjruoho 		"abcd/a",
15654bb1074Sjruoho 		"abcd/a/",
15754bb1074Sjruoho 		"abcd/ab",
15854bb1074Sjruoho 		"abcd/ab/",
15954bb1074Sjruoho 		"abcd/abc",
16054bb1074Sjruoho 		"abcd/abc/",
16154bb1074Sjruoho 		"abcd/abcd",
16254bb1074Sjruoho 		"abcd/abcd/",
16354bb1074Sjruoho 		"abcd/abcde",
16454bb1074Sjruoho 		"abcd/abcde/",
16554bb1074Sjruoho 		"abcd/abcdef",
16654bb1074Sjruoho 		"abcd/abcdef/",
16754bb1074Sjruoho 		"abcd/abcdefg",
16854bb1074Sjruoho 		"abcd/abcdefg/",
16954bb1074Sjruoho 		"abcd/abcdefgh",
17054bb1074Sjruoho 		"abcd/abcdefgh/",
17154bb1074Sjruoho 
17254bb1074Sjruoho 		"abcde/",
17354bb1074Sjruoho 		"abcde//",
17454bb1074Sjruoho 		"abcde/a",
17554bb1074Sjruoho 		"abcde/a/",
17654bb1074Sjruoho 		"abcde/ab",
17754bb1074Sjruoho 		"abcde/ab/",
17854bb1074Sjruoho 		"abcde/abc",
17954bb1074Sjruoho 		"abcde/abc/",
18054bb1074Sjruoho 		"abcde/abcd",
18154bb1074Sjruoho 		"abcde/abcd/",
18254bb1074Sjruoho 		"abcde/abcde",
18354bb1074Sjruoho 		"abcde/abcde/",
18454bb1074Sjruoho 		"abcde/abcdef",
18554bb1074Sjruoho 		"abcde/abcdef/",
18654bb1074Sjruoho 		"abcde/abcdefg",
18754bb1074Sjruoho 		"abcde/abcdefg/",
18854bb1074Sjruoho 		"abcde/abcdefgh",
18954bb1074Sjruoho 		"abcde/abcdefgh/",
19054bb1074Sjruoho 
19154bb1074Sjruoho 		"abcdef/",
19254bb1074Sjruoho 		"abcdef//",
19354bb1074Sjruoho 		"abcdef/a",
19454bb1074Sjruoho 		"abcdef/a/",
19554bb1074Sjruoho 		"abcdef/ab",
19654bb1074Sjruoho 		"abcdef/ab/",
19754bb1074Sjruoho 		"abcdef/abc",
19854bb1074Sjruoho 		"abcdef/abc/",
19954bb1074Sjruoho 		"abcdef/abcd",
20054bb1074Sjruoho 		"abcdef/abcd/",
20154bb1074Sjruoho 		"abcdef/abcde",
20254bb1074Sjruoho 		"abcdef/abcde/",
20354bb1074Sjruoho 		"abcdef/abcdef",
20454bb1074Sjruoho 		"abcdef/abcdef/",
20554bb1074Sjruoho 		"abcdef/abcdefg",
20654bb1074Sjruoho 		"abcdef/abcdefg/",
20754bb1074Sjruoho 		"abcdef/abcdefgh",
20854bb1074Sjruoho 		"abcdef/abcdefgh/",
20954bb1074Sjruoho 
21054bb1074Sjruoho 		"abcdefg/",
21154bb1074Sjruoho 		"abcdefg//",
21254bb1074Sjruoho 		"abcdefg/a",
21354bb1074Sjruoho 		"abcdefg/a/",
21454bb1074Sjruoho 		"abcdefg/ab",
21554bb1074Sjruoho 		"abcdefg/ab/",
21654bb1074Sjruoho 		"abcdefg/abc",
21754bb1074Sjruoho 		"abcdefg/abc/",
21854bb1074Sjruoho 		"abcdefg/abcd",
21954bb1074Sjruoho 		"abcdefg/abcd/",
22054bb1074Sjruoho 		"abcdefg/abcde",
22154bb1074Sjruoho 		"abcdefg/abcde/",
22254bb1074Sjruoho 		"abcdefg/abcdef",
22354bb1074Sjruoho 		"abcdefg/abcdef/",
22454bb1074Sjruoho 		"abcdefg/abcdefg",
22554bb1074Sjruoho 		"abcdefg/abcdefg/",
22654bb1074Sjruoho 		"abcdefg/abcdefgh",
22754bb1074Sjruoho 		"abcdefg/abcdefgh/",
22854bb1074Sjruoho 
22954bb1074Sjruoho 		"abcdefgh/",
23054bb1074Sjruoho 		"abcdefgh//",
23154bb1074Sjruoho 		"abcdefgh/a",
23254bb1074Sjruoho 		"abcdefgh/a/",
23354bb1074Sjruoho 		"abcdefgh/ab",
23454bb1074Sjruoho 		"abcdefgh/ab/",
23554bb1074Sjruoho 		"abcdefgh/abc",
23654bb1074Sjruoho 		"abcdefgh/abc/",
23754bb1074Sjruoho 		"abcdefgh/abcd",
23854bb1074Sjruoho 		"abcdefgh/abcd/",
23954bb1074Sjruoho 		"abcdefgh/abcde",
24054bb1074Sjruoho 		"abcdefgh/abcde/",
24154bb1074Sjruoho 		"abcdefgh/abcdef",
24254bb1074Sjruoho 		"abcdefgh/abcdef/",
24354bb1074Sjruoho 		"abcdefgh/abcdefg",
24454bb1074Sjruoho 		"abcdefgh/abcdefg/",
24554bb1074Sjruoho 		"abcdefgh/abcdefgh",
24654bb1074Sjruoho 		"abcdefgh/abcdefgh/",
24754bb1074Sjruoho 	};
24854bb1074Sjruoho 
2490480186dSchristos 	dl_handle = dlopen(NULL, RTLD_LAZY);
250*e20f7376Schristos 	strchr_fn = dlsym(dl_handle, "test_strchr");
25154bb1074Sjruoho 	if (!strchr_fn)
25254bb1074Sjruoho 		strchr_fn = strchr;
25354bb1074Sjruoho 
25454bb1074Sjruoho 	for (a = 3; a < 3 + sizeof(long); ++a) {
25554bb1074Sjruoho 		/* Put char and a \0 before the buffer */
25654bb1074Sjruoho 		buf[a-1] = '/';
25754bb1074Sjruoho 		buf[a-2] = '0';
25854bb1074Sjruoho 		buf[a-3] = 0xff;
25954bb1074Sjruoho 		for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
26054bb1074Sjruoho 			int len = strlen(tab[t]) + 1;
26154bb1074Sjruoho 			memcpy(&buf[a], tab[t], len);
26254bb1074Sjruoho 
26354bb1074Sjruoho 			/* Put the char we are looking for after the \0 */
26454bb1074Sjruoho 			buf[a + len] = '/';
26554bb1074Sjruoho 
26654bb1074Sjruoho 			/* Check search for NUL at end of string */
26754bb1074Sjruoho 			verify_strchr(buf + a, 0, t, a);
26854bb1074Sjruoho 
26954bb1074Sjruoho 			/* Then for the '/' in the strings */
27054bb1074Sjruoho 			verify_strchr(buf + a, '/', t, a);
27154bb1074Sjruoho 
27254bb1074Sjruoho 			/* check zero extension of char arg */
27354bb1074Sjruoho 			verify_strchr(buf + a, 0xffffff00 | '/', t, a);
27454bb1074Sjruoho 
27554bb1074Sjruoho 			/* Replace all the '/' with 0xff */
27654bb1074Sjruoho 			while ((off = slow_strchr(buf + a, '/')) != NULL)
27754bb1074Sjruoho 				*off = 0xff;
27854bb1074Sjruoho 
27954bb1074Sjruoho 			buf[a + len] = 0xff;
28054bb1074Sjruoho 
28154bb1074Sjruoho 			/* Check we can search for 0xff as well as '/' */
28254bb1074Sjruoho 			verify_strchr(buf + a, 0xff, t, a);
28354bb1074Sjruoho 		}
28454bb1074Sjruoho 	}
2850480186dSchristos 	(void)dlclose(dl_handle);
28654bb1074Sjruoho }
28754bb1074Sjruoho 
ATF_TP_ADD_TCS(tp)28854bb1074Sjruoho ATF_TP_ADD_TCS(tp)
28954bb1074Sjruoho {
29054bb1074Sjruoho 
29154bb1074Sjruoho 	ATF_TP_ADD_TC(tp, strchr_basic);
29254bb1074Sjruoho 
29354bb1074Sjruoho 	return atf_no_error();
29454bb1074Sjruoho }
295