1*606d0e4aSDag-Erling Smørgrav /* $NetBSD: t_strchr.c,v 1.3 2023/01/30 19:49:49 christos Exp $ */
257718be8SEnji Cooper
357718be8SEnji Cooper /*
457718be8SEnji Cooper * Written by J.T. Conklin <jtc@acorntoolworks.com>
557718be8SEnji Cooper * Public domain.
657718be8SEnji Cooper */
757718be8SEnji Cooper
857718be8SEnji Cooper #include <atf-c.h>
957718be8SEnji Cooper #include <string.h>
1057718be8SEnji Cooper #include <unistd.h>
1157718be8SEnji Cooper #include <stdio.h>
1257718be8SEnji Cooper #include <stdlib.h>
1357718be8SEnji Cooper #include <dlfcn.h>
1457718be8SEnji Cooper
1557718be8SEnji Cooper static char *slow_strchr(char *, int);
1657718be8SEnji Cooper static void verify_strchr(char *, int, unsigned int, unsigned int);
1757718be8SEnji Cooper
1857718be8SEnji Cooper char * (*volatile strchr_fn)(const char *, int);
1957718be8SEnji Cooper
2057718be8SEnji Cooper static char *
slow_strchr(char * buf,int ch)2157718be8SEnji Cooper slow_strchr(char *buf, int ch)
2257718be8SEnji Cooper {
2357718be8SEnji Cooper unsigned char c = 1;
2457718be8SEnji Cooper
2557718be8SEnji Cooper ch &= 0xff;
2657718be8SEnji Cooper
2757718be8SEnji Cooper for (; c != 0; buf++) {
2857718be8SEnji Cooper c = *buf;
2957718be8SEnji Cooper if (c == ch)
3057718be8SEnji Cooper return buf;
3157718be8SEnji Cooper }
3257718be8SEnji Cooper return 0;
3357718be8SEnji Cooper }
3457718be8SEnji Cooper
3557718be8SEnji Cooper static void
verify_strchr(char * buf,int ch,unsigned int t,unsigned int a)3657718be8SEnji Cooper verify_strchr(char *buf, int ch, unsigned int t, unsigned int a)
3757718be8SEnji Cooper {
3857718be8SEnji Cooper const char *off, *ok_off;
3957718be8SEnji Cooper
4057718be8SEnji Cooper off = strchr_fn(buf, ch);
4157718be8SEnji Cooper ok_off = slow_strchr(buf, ch);
4257718be8SEnji Cooper if (off == ok_off)
4357718be8SEnji Cooper return;
4457718be8SEnji Cooper
4557718be8SEnji Cooper fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, "
4657718be8SEnji Cooper "alignment %d)\n",
4757718be8SEnji Cooper buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a);
4857718be8SEnji Cooper
4957718be8SEnji Cooper atf_tc_fail("Check stderr for details");
5057718be8SEnji Cooper }
5157718be8SEnji Cooper
5257718be8SEnji Cooper ATF_TC(strchr_basic);
ATF_TC_HEAD(strchr_basic,tc)5357718be8SEnji Cooper ATF_TC_HEAD(strchr_basic, tc)
5457718be8SEnji Cooper {
5557718be8SEnji Cooper
5657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strchr(3) results");
5757718be8SEnji Cooper }
5857718be8SEnji Cooper
ATF_TC_BODY(strchr_basic,tc)5957718be8SEnji Cooper ATF_TC_BODY(strchr_basic, tc)
6057718be8SEnji Cooper {
6183e8b13fSEnji Cooper void *dl_handle;
6257718be8SEnji Cooper char *off;
6357718be8SEnji Cooper char buf[32];
64ddba0402SEnji Cooper unsigned int t, a;
6557718be8SEnji Cooper
6657718be8SEnji Cooper const char *tab[] = {
6757718be8SEnji Cooper "",
6857718be8SEnji Cooper "a",
6957718be8SEnji Cooper "aa",
7057718be8SEnji Cooper "abc",
7157718be8SEnji Cooper "abcd",
7257718be8SEnji Cooper "abcde",
7357718be8SEnji Cooper "abcdef",
7457718be8SEnji Cooper "abcdefg",
7557718be8SEnji Cooper "abcdefgh",
7657718be8SEnji Cooper
7757718be8SEnji Cooper "/",
7857718be8SEnji Cooper "//",
7957718be8SEnji Cooper "/a",
8057718be8SEnji Cooper "/a/",
8157718be8SEnji Cooper "/ab",
8257718be8SEnji Cooper "/ab/",
8357718be8SEnji Cooper "/abc",
8457718be8SEnji Cooper "/abc/",
8557718be8SEnji Cooper "/abcd",
8657718be8SEnji Cooper "/abcd/",
8757718be8SEnji Cooper "/abcde",
8857718be8SEnji Cooper "/abcde/",
8957718be8SEnji Cooper "/abcdef",
9057718be8SEnji Cooper "/abcdef/",
9157718be8SEnji Cooper "/abcdefg",
9257718be8SEnji Cooper "/abcdefg/",
9357718be8SEnji Cooper "/abcdefgh",
9457718be8SEnji Cooper "/abcdefgh/",
9557718be8SEnji Cooper
9657718be8SEnji Cooper "a/",
9757718be8SEnji Cooper "a//",
9857718be8SEnji Cooper "a/a",
9957718be8SEnji Cooper "a/a/",
10057718be8SEnji Cooper "a/ab",
10157718be8SEnji Cooper "a/ab/",
10257718be8SEnji Cooper "a/abc",
10357718be8SEnji Cooper "a/abc/",
10457718be8SEnji Cooper "a/abcd",
10557718be8SEnji Cooper "a/abcd/",
10657718be8SEnji Cooper "a/abcde",
10757718be8SEnji Cooper "a/abcde/",
10857718be8SEnji Cooper "a/abcdef",
10957718be8SEnji Cooper "a/abcdef/",
11057718be8SEnji Cooper "a/abcdefg",
11157718be8SEnji Cooper "a/abcdefg/",
11257718be8SEnji Cooper "a/abcdefgh",
11357718be8SEnji Cooper "a/abcdefgh/",
11457718be8SEnji Cooper
11557718be8SEnji Cooper "ab/",
11657718be8SEnji Cooper "ab//",
11757718be8SEnji Cooper "ab/a",
11857718be8SEnji Cooper "ab/a/",
11957718be8SEnji Cooper "ab/ab",
12057718be8SEnji Cooper "ab/ab/",
12157718be8SEnji Cooper "ab/abc",
12257718be8SEnji Cooper "ab/abc/",
12357718be8SEnji Cooper "ab/abcd",
12457718be8SEnji Cooper "ab/abcd/",
12557718be8SEnji Cooper "ab/abcde",
12657718be8SEnji Cooper "ab/abcde/",
12757718be8SEnji Cooper "ab/abcdef",
12857718be8SEnji Cooper "ab/abcdef/",
12957718be8SEnji Cooper "ab/abcdefg",
13057718be8SEnji Cooper "ab/abcdefg/",
13157718be8SEnji Cooper "ab/abcdefgh",
13257718be8SEnji Cooper "ab/abcdefgh/",
13357718be8SEnji Cooper
13457718be8SEnji Cooper "abc/",
13557718be8SEnji Cooper "abc//",
13657718be8SEnji Cooper "abc/a",
13757718be8SEnji Cooper "abc/a/",
13857718be8SEnji Cooper "abc/ab",
13957718be8SEnji Cooper "abc/ab/",
14057718be8SEnji Cooper "abc/abc",
14157718be8SEnji Cooper "abc/abc/",
14257718be8SEnji Cooper "abc/abcd",
14357718be8SEnji Cooper "abc/abcd/",
14457718be8SEnji Cooper "abc/abcde",
14557718be8SEnji Cooper "abc/abcde/",
14657718be8SEnji Cooper "abc/abcdef",
14757718be8SEnji Cooper "abc/abcdef/",
14857718be8SEnji Cooper "abc/abcdefg",
14957718be8SEnji Cooper "abc/abcdefg/",
15057718be8SEnji Cooper "abc/abcdefgh",
15157718be8SEnji Cooper "abc/abcdefgh/",
15257718be8SEnji Cooper
15357718be8SEnji Cooper "abcd/",
15457718be8SEnji Cooper "abcd//",
15557718be8SEnji Cooper "abcd/a",
15657718be8SEnji Cooper "abcd/a/",
15757718be8SEnji Cooper "abcd/ab",
15857718be8SEnji Cooper "abcd/ab/",
15957718be8SEnji Cooper "abcd/abc",
16057718be8SEnji Cooper "abcd/abc/",
16157718be8SEnji Cooper "abcd/abcd",
16257718be8SEnji Cooper "abcd/abcd/",
16357718be8SEnji Cooper "abcd/abcde",
16457718be8SEnji Cooper "abcd/abcde/",
16557718be8SEnji Cooper "abcd/abcdef",
16657718be8SEnji Cooper "abcd/abcdef/",
16757718be8SEnji Cooper "abcd/abcdefg",
16857718be8SEnji Cooper "abcd/abcdefg/",
16957718be8SEnji Cooper "abcd/abcdefgh",
17057718be8SEnji Cooper "abcd/abcdefgh/",
17157718be8SEnji Cooper
17257718be8SEnji Cooper "abcde/",
17357718be8SEnji Cooper "abcde//",
17457718be8SEnji Cooper "abcde/a",
17557718be8SEnji Cooper "abcde/a/",
17657718be8SEnji Cooper "abcde/ab",
17757718be8SEnji Cooper "abcde/ab/",
17857718be8SEnji Cooper "abcde/abc",
17957718be8SEnji Cooper "abcde/abc/",
18057718be8SEnji Cooper "abcde/abcd",
18157718be8SEnji Cooper "abcde/abcd/",
18257718be8SEnji Cooper "abcde/abcde",
18357718be8SEnji Cooper "abcde/abcde/",
18457718be8SEnji Cooper "abcde/abcdef",
18557718be8SEnji Cooper "abcde/abcdef/",
18657718be8SEnji Cooper "abcde/abcdefg",
18757718be8SEnji Cooper "abcde/abcdefg/",
18857718be8SEnji Cooper "abcde/abcdefgh",
18957718be8SEnji Cooper "abcde/abcdefgh/",
19057718be8SEnji Cooper
19157718be8SEnji Cooper "abcdef/",
19257718be8SEnji Cooper "abcdef//",
19357718be8SEnji Cooper "abcdef/a",
19457718be8SEnji Cooper "abcdef/a/",
19557718be8SEnji Cooper "abcdef/ab",
19657718be8SEnji Cooper "abcdef/ab/",
19757718be8SEnji Cooper "abcdef/abc",
19857718be8SEnji Cooper "abcdef/abc/",
19957718be8SEnji Cooper "abcdef/abcd",
20057718be8SEnji Cooper "abcdef/abcd/",
20157718be8SEnji Cooper "abcdef/abcde",
20257718be8SEnji Cooper "abcdef/abcde/",
20357718be8SEnji Cooper "abcdef/abcdef",
20457718be8SEnji Cooper "abcdef/abcdef/",
20557718be8SEnji Cooper "abcdef/abcdefg",
20657718be8SEnji Cooper "abcdef/abcdefg/",
20757718be8SEnji Cooper "abcdef/abcdefgh",
20857718be8SEnji Cooper "abcdef/abcdefgh/",
20957718be8SEnji Cooper
21057718be8SEnji Cooper "abcdefg/",
21157718be8SEnji Cooper "abcdefg//",
21257718be8SEnji Cooper "abcdefg/a",
21357718be8SEnji Cooper "abcdefg/a/",
21457718be8SEnji Cooper "abcdefg/ab",
21557718be8SEnji Cooper "abcdefg/ab/",
21657718be8SEnji Cooper "abcdefg/abc",
21757718be8SEnji Cooper "abcdefg/abc/",
21857718be8SEnji Cooper "abcdefg/abcd",
21957718be8SEnji Cooper "abcdefg/abcd/",
22057718be8SEnji Cooper "abcdefg/abcde",
22157718be8SEnji Cooper "abcdefg/abcde/",
22257718be8SEnji Cooper "abcdefg/abcdef",
22357718be8SEnji Cooper "abcdefg/abcdef/",
22457718be8SEnji Cooper "abcdefg/abcdefg",
22557718be8SEnji Cooper "abcdefg/abcdefg/",
22657718be8SEnji Cooper "abcdefg/abcdefgh",
22757718be8SEnji Cooper "abcdefg/abcdefgh/",
22857718be8SEnji Cooper
22957718be8SEnji Cooper "abcdefgh/",
23057718be8SEnji Cooper "abcdefgh//",
23157718be8SEnji Cooper "abcdefgh/a",
23257718be8SEnji Cooper "abcdefgh/a/",
23357718be8SEnji Cooper "abcdefgh/ab",
23457718be8SEnji Cooper "abcdefgh/ab/",
23557718be8SEnji Cooper "abcdefgh/abc",
23657718be8SEnji Cooper "abcdefgh/abc/",
23757718be8SEnji Cooper "abcdefgh/abcd",
23857718be8SEnji Cooper "abcdefgh/abcd/",
23957718be8SEnji Cooper "abcdefgh/abcde",
24057718be8SEnji Cooper "abcdefgh/abcde/",
24157718be8SEnji Cooper "abcdefgh/abcdef",
24257718be8SEnji Cooper "abcdefgh/abcdef/",
24357718be8SEnji Cooper "abcdefgh/abcdefg",
24457718be8SEnji Cooper "abcdefgh/abcdefg/",
24557718be8SEnji Cooper "abcdefgh/abcdefgh",
24657718be8SEnji Cooper "abcdefgh/abcdefgh/",
24757718be8SEnji Cooper };
24857718be8SEnji Cooper
24983e8b13fSEnji Cooper dl_handle = dlopen(NULL, RTLD_LAZY);
250*606d0e4aSDag-Erling Smørgrav strchr_fn = dlsym(dl_handle, "test_strchr");
25157718be8SEnji Cooper if (!strchr_fn)
25257718be8SEnji Cooper strchr_fn = strchr;
25357718be8SEnji Cooper
25457718be8SEnji Cooper for (a = 3; a < 3 + sizeof(long); ++a) {
25557718be8SEnji Cooper /* Put char and a \0 before the buffer */
25657718be8SEnji Cooper buf[a-1] = '/';
25757718be8SEnji Cooper buf[a-2] = '0';
25857718be8SEnji Cooper buf[a-3] = 0xff;
25957718be8SEnji Cooper for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
26057718be8SEnji Cooper int len = strlen(tab[t]) + 1;
26157718be8SEnji Cooper memcpy(&buf[a], tab[t], len);
26257718be8SEnji Cooper
26357718be8SEnji Cooper /* Put the char we are looking for after the \0 */
26457718be8SEnji Cooper buf[a + len] = '/';
26557718be8SEnji Cooper
26657718be8SEnji Cooper /* Check search for NUL at end of string */
26757718be8SEnji Cooper verify_strchr(buf + a, 0, t, a);
26857718be8SEnji Cooper
26957718be8SEnji Cooper /* Then for the '/' in the strings */
27057718be8SEnji Cooper verify_strchr(buf + a, '/', t, a);
27157718be8SEnji Cooper
27257718be8SEnji Cooper /* check zero extension of char arg */
27357718be8SEnji Cooper verify_strchr(buf + a, 0xffffff00 | '/', t, a);
27457718be8SEnji Cooper
27557718be8SEnji Cooper /* Replace all the '/' with 0xff */
27657718be8SEnji Cooper while ((off = slow_strchr(buf + a, '/')) != NULL)
27757718be8SEnji Cooper *off = 0xff;
27857718be8SEnji Cooper
27957718be8SEnji Cooper buf[a + len] = 0xff;
28057718be8SEnji Cooper
28157718be8SEnji Cooper /* Check we can search for 0xff as well as '/' */
28257718be8SEnji Cooper verify_strchr(buf + a, 0xff, t, a);
28357718be8SEnji Cooper }
28457718be8SEnji Cooper }
28583e8b13fSEnji Cooper (void)dlclose(dl_handle);
28657718be8SEnji Cooper }
28757718be8SEnji Cooper
ATF_TP_ADD_TCS(tp)28857718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
28957718be8SEnji Cooper {
29057718be8SEnji Cooper
29157718be8SEnji Cooper ATF_TP_ADD_TC(tp, strchr_basic);
29257718be8SEnji Cooper
29357718be8SEnji Cooper return atf_no_error();
29457718be8SEnji Cooper }
295