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