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