1*11be35a1SLionel Sambuc /* $NetBSD: t_strlen.c,v 1.5 2011/07/14 07:33:20 jruoho Exp $ */
2*11be35a1SLionel Sambuc
3*11be35a1SLionel Sambuc /*
4*11be35a1SLionel Sambuc * Written by J.T. Conklin <jtc@acorntoolworks.com>
5*11be35a1SLionel Sambuc * Public domain.
6*11be35a1SLionel Sambuc */
7*11be35a1SLionel Sambuc
8*11be35a1SLionel Sambuc #include <atf-c.h>
9*11be35a1SLionel Sambuc #include <string.h>
10*11be35a1SLionel Sambuc #include <unistd.h>
11*11be35a1SLionel Sambuc #include <stdio.h>
12*11be35a1SLionel Sambuc #include <stdlib.h>
13*11be35a1SLionel Sambuc #include <dlfcn.h>
14*11be35a1SLionel Sambuc #include <unistd.h>
15*11be35a1SLionel Sambuc
16*11be35a1SLionel Sambuc static void write_num(int);
17*11be35a1SLionel Sambuc
18*11be35a1SLionel Sambuc static void
write_num(int val)19*11be35a1SLionel Sambuc write_num(int val)
20*11be35a1SLionel Sambuc {
21*11be35a1SLionel Sambuc char buf[20];
22*11be35a1SLionel Sambuc int i;
23*11be35a1SLionel Sambuc
24*11be35a1SLionel Sambuc for (i = sizeof buf; --i >= 0;) {
25*11be35a1SLionel Sambuc buf[i] = '0' + val % 10;
26*11be35a1SLionel Sambuc val /= 10;
27*11be35a1SLionel Sambuc if (val == 0) {
28*11be35a1SLionel Sambuc write(2, buf + i, sizeof buf - i);
29*11be35a1SLionel Sambuc return;
30*11be35a1SLionel Sambuc }
31*11be35a1SLionel Sambuc }
32*11be35a1SLionel Sambuc write(2, "overflow", 8);
33*11be35a1SLionel Sambuc }
34*11be35a1SLionel Sambuc
35*11be35a1SLionel Sambuc ATF_TC(strlen_basic);
ATF_TC_HEAD(strlen_basic,tc)36*11be35a1SLionel Sambuc ATF_TC_HEAD(strlen_basic, tc)
37*11be35a1SLionel Sambuc {
38*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test strlen(3) results");
39*11be35a1SLionel Sambuc }
40*11be35a1SLionel Sambuc
ATF_TC_BODY(strlen_basic,tc)41*11be35a1SLionel Sambuc ATF_TC_BODY(strlen_basic, tc)
42*11be35a1SLionel Sambuc {
43*11be35a1SLionel Sambuc /* try to trick the compiler */
44*11be35a1SLionel Sambuc size_t (*strlen_fn)(const char *);
45*11be35a1SLionel Sambuc
46*11be35a1SLionel Sambuc unsigned int a, t;
47*11be35a1SLionel Sambuc size_t len;
48*11be35a1SLionel Sambuc char buf[64];
49*11be35a1SLionel Sambuc
50*11be35a1SLionel Sambuc struct tab {
51*11be35a1SLionel Sambuc const char* val;
52*11be35a1SLionel Sambuc size_t len;
53*11be35a1SLionel Sambuc };
54*11be35a1SLionel Sambuc
55*11be35a1SLionel Sambuc const struct tab tab[] = {
56*11be35a1SLionel Sambuc /*
57*11be35a1SLionel Sambuc * patterns that check for all combinations of leading and
58*11be35a1SLionel Sambuc * trailing unaligned characters (on a 64 bit processor)
59*11be35a1SLionel Sambuc */
60*11be35a1SLionel Sambuc
61*11be35a1SLionel Sambuc { "", 0 },
62*11be35a1SLionel Sambuc { "a", 1 },
63*11be35a1SLionel Sambuc { "ab", 2 },
64*11be35a1SLionel Sambuc { "abc", 3 },
65*11be35a1SLionel Sambuc { "abcd", 4 },
66*11be35a1SLionel Sambuc { "abcde", 5 },
67*11be35a1SLionel Sambuc { "abcdef", 6 },
68*11be35a1SLionel Sambuc { "abcdefg", 7 },
69*11be35a1SLionel Sambuc { "abcdefgh", 8 },
70*11be35a1SLionel Sambuc { "abcdefghi", 9 },
71*11be35a1SLionel Sambuc { "abcdefghij", 10 },
72*11be35a1SLionel Sambuc { "abcdefghijk", 11 },
73*11be35a1SLionel Sambuc { "abcdefghijkl", 12 },
74*11be35a1SLionel Sambuc { "abcdefghijklm", 13 },
75*11be35a1SLionel Sambuc { "abcdefghijklmn", 14 },
76*11be35a1SLionel Sambuc { "abcdefghijklmno", 15 },
77*11be35a1SLionel Sambuc { "abcdefghijklmnop", 16 },
78*11be35a1SLionel Sambuc { "abcdefghijklmnopq", 17 },
79*11be35a1SLionel Sambuc { "abcdefghijklmnopqr", 18 },
80*11be35a1SLionel Sambuc { "abcdefghijklmnopqrs", 19 },
81*11be35a1SLionel Sambuc { "abcdefghijklmnopqrst", 20 },
82*11be35a1SLionel Sambuc { "abcdefghijklmnopqrstu", 21 },
83*11be35a1SLionel Sambuc { "abcdefghijklmnopqrstuv", 22 },
84*11be35a1SLionel Sambuc { "abcdefghijklmnopqrstuvw", 23 },
85*11be35a1SLionel Sambuc
86*11be35a1SLionel Sambuc /*
87*11be35a1SLionel Sambuc * patterns that check for the cases where the expression:
88*11be35a1SLionel Sambuc *
89*11be35a1SLionel Sambuc * ((word - 0x7f7f..7f) & 0x8080..80)
90*11be35a1SLionel Sambuc *
91*11be35a1SLionel Sambuc * returns non-zero even though there are no zero bytes in
92*11be35a1SLionel Sambuc * the word.
93*11be35a1SLionel Sambuc */
94*11be35a1SLionel Sambuc
95*11be35a1SLionel Sambuc { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 },
96*11be35a1SLionel Sambuc { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 },
97*11be35a1SLionel Sambuc { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 },
98*11be35a1SLionel Sambuc { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 },
99*11be35a1SLionel Sambuc { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 },
100*11be35a1SLionel Sambuc { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 },
101*11be35a1SLionel Sambuc { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 },
102*11be35a1SLionel Sambuc { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 },
103*11be35a1SLionel Sambuc { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 },
104*11be35a1SLionel Sambuc };
105*11be35a1SLionel Sambuc
106*11be35a1SLionel Sambuc /*
107*11be35a1SLionel Sambuc * During testing it is useful have the rest of the program
108*11be35a1SLionel Sambuc * use a known good version!
109*11be35a1SLionel Sambuc */
110*11be35a1SLionel Sambuc strlen_fn = dlsym(dlopen(NULL, RTLD_LAZY), "test_strlen");
111*11be35a1SLionel Sambuc if (!strlen_fn)
112*11be35a1SLionel Sambuc strlen_fn = strlen;
113*11be35a1SLionel Sambuc
114*11be35a1SLionel Sambuc for (a = 0; a < sizeof(long); ++a) {
115*11be35a1SLionel Sambuc for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
116*11be35a1SLionel Sambuc
117*11be35a1SLionel Sambuc memcpy(&buf[a], tab[t].val, tab[t].len + 1);
118*11be35a1SLionel Sambuc len = strlen_fn(&buf[a]);
119*11be35a1SLionel Sambuc
120*11be35a1SLionel Sambuc if (len != tab[t].len) {
121*11be35a1SLionel Sambuc /* Write error without using printf / strlen */
122*11be35a1SLionel Sambuc write(2, "alignment ", 10);
123*11be35a1SLionel Sambuc write_num(a);
124*11be35a1SLionel Sambuc write(2, ", test ", 7);
125*11be35a1SLionel Sambuc write_num(t);
126*11be35a1SLionel Sambuc write(2, ", got len ", 10);
127*11be35a1SLionel Sambuc write_num(len);
128*11be35a1SLionel Sambuc write(2, ", not ", 6);
129*11be35a1SLionel Sambuc write_num(tab[t].len);
130*11be35a1SLionel Sambuc write(2, ", for '", 7);
131*11be35a1SLionel Sambuc write(2, tab[t].val, tab[t].len);
132*11be35a1SLionel Sambuc write(2, "'\n", 2);
133*11be35a1SLionel Sambuc atf_tc_fail("See stderr for details");
134*11be35a1SLionel Sambuc }
135*11be35a1SLionel Sambuc }
136*11be35a1SLionel Sambuc }
137*11be35a1SLionel Sambuc }
138*11be35a1SLionel Sambuc
139*11be35a1SLionel Sambuc ATF_TC(strlen_huge);
ATF_TC_HEAD(strlen_huge,tc)140*11be35a1SLionel Sambuc ATF_TC_HEAD(strlen_huge, tc)
141*11be35a1SLionel Sambuc {
142*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings");
143*11be35a1SLionel Sambuc }
144*11be35a1SLionel Sambuc
ATF_TC_BODY(strlen_huge,tc)145*11be35a1SLionel Sambuc ATF_TC_BODY(strlen_huge, tc)
146*11be35a1SLionel Sambuc {
147*11be35a1SLionel Sambuc long page;
148*11be35a1SLionel Sambuc char *str;
149*11be35a1SLionel Sambuc size_t i;
150*11be35a1SLionel Sambuc
151*11be35a1SLionel Sambuc page = sysconf(_SC_PAGESIZE);
152*11be35a1SLionel Sambuc ATF_REQUIRE(page >= 0);
153*11be35a1SLionel Sambuc
154*11be35a1SLionel Sambuc for (i = 1; i < 1000; i = i + 100) {
155*11be35a1SLionel Sambuc
156*11be35a1SLionel Sambuc str = malloc(i * page + 1);
157*11be35a1SLionel Sambuc
158*11be35a1SLionel Sambuc if (str == NULL)
159*11be35a1SLionel Sambuc continue;
160*11be35a1SLionel Sambuc
161*11be35a1SLionel Sambuc (void)memset(str, 'x', i * page);
162*11be35a1SLionel Sambuc str[i * page] = '\0';
163*11be35a1SLionel Sambuc
164*11be35a1SLionel Sambuc ATF_REQUIRE(strlen(str) == i * page);
165*11be35a1SLionel Sambuc free(str);
166*11be35a1SLionel Sambuc }
167*11be35a1SLionel Sambuc }
168*11be35a1SLionel Sambuc
169*11be35a1SLionel Sambuc ATF_TC(strnlen_basic);
ATF_TC_HEAD(strnlen_basic,tc)170*11be35a1SLionel Sambuc ATF_TC_HEAD(strnlen_basic, tc)
171*11be35a1SLionel Sambuc {
172*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)");
173*11be35a1SLionel Sambuc }
174*11be35a1SLionel Sambuc
ATF_TC_BODY(strnlen_basic,tc)175*11be35a1SLionel Sambuc ATF_TC_BODY(strnlen_basic, tc)
176*11be35a1SLionel Sambuc {
177*11be35a1SLionel Sambuc char buf[1];
178*11be35a1SLionel Sambuc
179*11be35a1SLionel Sambuc buf[0] = '\0';
180*11be35a1SLionel Sambuc
181*11be35a1SLionel Sambuc ATF_CHECK(strnlen(buf, 000) == 0);
182*11be35a1SLionel Sambuc ATF_CHECK(strnlen(buf, 111) == 0);
183*11be35a1SLionel Sambuc
184*11be35a1SLionel Sambuc ATF_CHECK(strnlen("xxx", 0) == 0);
185*11be35a1SLionel Sambuc ATF_CHECK(strnlen("xxx", 1) == 1);
186*11be35a1SLionel Sambuc ATF_CHECK(strnlen("xxx", 2) == 2);
187*11be35a1SLionel Sambuc ATF_CHECK(strnlen("xxx", 3) == 3);
188*11be35a1SLionel Sambuc ATF_CHECK(strnlen("xxx", 9) == 3);
189*11be35a1SLionel Sambuc }
190*11be35a1SLionel Sambuc
ATF_TP_ADD_TCS(tp)191*11be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp)
192*11be35a1SLionel Sambuc {
193*11be35a1SLionel Sambuc
194*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, strlen_basic);
195*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, strlen_huge);
196*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, strnlen_basic);
197*11be35a1SLionel Sambuc
198*11be35a1SLionel Sambuc return atf_no_error();
199*11be35a1SLionel Sambuc }
200