xref: /netbsd-src/tests/lib/libc/string/t_strlen.c (revision cd517fb06cfb507bb5cac3d3b698ca5f77ea7cb7)
1*cd517fb0Schristos /* $NetBSD: t_strlen.c,v 1.6 2017/01/14 20:49:24 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>
14b34acef4Sjruoho #include <unistd.h>
1554bb1074Sjruoho 
1654bb1074Sjruoho static void	write_num(int);
1754bb1074Sjruoho 
1854bb1074Sjruoho static void
write_num(int val)1954bb1074Sjruoho write_num(int val)
2054bb1074Sjruoho {
2154bb1074Sjruoho 	char buf[20];
2254bb1074Sjruoho 	int i;
2354bb1074Sjruoho 
2454bb1074Sjruoho 	for (i = sizeof buf; --i >= 0;) {
2554bb1074Sjruoho 		buf[i] = '0' + val % 10;
2654bb1074Sjruoho 		val /= 10;
2754bb1074Sjruoho 		if (val == 0) {
2854bb1074Sjruoho 			write(2, buf + i, sizeof buf - i);
2954bb1074Sjruoho 			return;
3054bb1074Sjruoho 		}
3154bb1074Sjruoho 	}
3254bb1074Sjruoho 	write(2, "overflow", 8);
3354bb1074Sjruoho }
3454bb1074Sjruoho 
3554bb1074Sjruoho ATF_TC(strlen_basic);
ATF_TC_HEAD(strlen_basic,tc)3654bb1074Sjruoho ATF_TC_HEAD(strlen_basic, tc)
3754bb1074Sjruoho {
3854bb1074Sjruoho         atf_tc_set_md_var(tc, "descr", "Test strlen(3) results");
3954bb1074Sjruoho }
4054bb1074Sjruoho 
ATF_TC_BODY(strlen_basic,tc)4154bb1074Sjruoho ATF_TC_BODY(strlen_basic, tc)
4254bb1074Sjruoho {
43*cd517fb0Schristos 	void *dl_handle;
4454bb1074Sjruoho 	/* try to trick the compiler */
4554bb1074Sjruoho 	size_t (*strlen_fn)(const char *);
4654bb1074Sjruoho 
4754bb1074Sjruoho 	unsigned int a, t;
4854bb1074Sjruoho 	size_t len;
4954bb1074Sjruoho 	char buf[64];
5054bb1074Sjruoho 
5154bb1074Sjruoho 	struct tab {
5254bb1074Sjruoho 		const char*	val;
5354bb1074Sjruoho 		size_t		len;
5454bb1074Sjruoho 	};
5554bb1074Sjruoho 
5654bb1074Sjruoho 	const struct tab tab[] = {
5754bb1074Sjruoho 		/*
5854bb1074Sjruoho 		 * patterns that check for all combinations of leading and
5954bb1074Sjruoho 		 * trailing unaligned characters (on a 64 bit processor)
6054bb1074Sjruoho 		 */
6154bb1074Sjruoho 
6254bb1074Sjruoho 		{ "",				0 },
6354bb1074Sjruoho 		{ "a",				1 },
6454bb1074Sjruoho 		{ "ab",				2 },
6554bb1074Sjruoho 		{ "abc",			3 },
6654bb1074Sjruoho 		{ "abcd",			4 },
6754bb1074Sjruoho 		{ "abcde",			5 },
6854bb1074Sjruoho 		{ "abcdef",			6 },
6954bb1074Sjruoho 		{ "abcdefg",			7 },
7054bb1074Sjruoho 		{ "abcdefgh",			8 },
7154bb1074Sjruoho 		{ "abcdefghi",			9 },
7254bb1074Sjruoho 		{ "abcdefghij",			10 },
7354bb1074Sjruoho 		{ "abcdefghijk",		11 },
7454bb1074Sjruoho 		{ "abcdefghijkl",		12 },
7554bb1074Sjruoho 		{ "abcdefghijklm",		13 },
7654bb1074Sjruoho 		{ "abcdefghijklmn",		14 },
7754bb1074Sjruoho 		{ "abcdefghijklmno",		15 },
7854bb1074Sjruoho 		{ "abcdefghijklmnop",		16 },
7954bb1074Sjruoho 		{ "abcdefghijklmnopq",		17 },
8054bb1074Sjruoho 		{ "abcdefghijklmnopqr",		18 },
8154bb1074Sjruoho 		{ "abcdefghijklmnopqrs",	19 },
8254bb1074Sjruoho 		{ "abcdefghijklmnopqrst",	20 },
8354bb1074Sjruoho 		{ "abcdefghijklmnopqrstu",	21 },
8454bb1074Sjruoho 		{ "abcdefghijklmnopqrstuv",	22 },
8554bb1074Sjruoho 		{ "abcdefghijklmnopqrstuvw",	23 },
8654bb1074Sjruoho 
8754bb1074Sjruoho 		/*
8854bb1074Sjruoho 		 * patterns that check for the cases where the expression:
8954bb1074Sjruoho 		 *
9054bb1074Sjruoho 		 *	((word - 0x7f7f..7f) & 0x8080..80)
9154bb1074Sjruoho 		 *
9254bb1074Sjruoho 		 * returns non-zero even though there are no zero bytes in
9354bb1074Sjruoho 		 * the word.
9454bb1074Sjruoho 		 */
9554bb1074Sjruoho 
9654bb1074Sjruoho 		{ "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh",	16 },
9754bb1074Sjruoho 		{ "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh",	16 },
9854bb1074Sjruoho 		{ "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh",	16 },
9954bb1074Sjruoho 		{ "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh",	16 },
10054bb1074Sjruoho 		{ "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh",	16 },
10154bb1074Sjruoho 		{ "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh",	16 },
10254bb1074Sjruoho 		{ "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh",	16 },
10354bb1074Sjruoho 		{ "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h",	16 },
10454bb1074Sjruoho 		{ "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "",	16 },
10554bb1074Sjruoho 	};
10654bb1074Sjruoho 
10754bb1074Sjruoho 	/*
10854bb1074Sjruoho 	 * During testing it is useful have the rest of the program
10954bb1074Sjruoho 	 * use a known good version!
11054bb1074Sjruoho 	 */
111*cd517fb0Schristos 	dl_handle = dlopen(NULL, RTLD_LAZY);
112*cd517fb0Schristos 	strlen_fn = dlsym(dl_handle, "test_strlen");
11354bb1074Sjruoho 	if (!strlen_fn)
11454bb1074Sjruoho 		strlen_fn = strlen;
11554bb1074Sjruoho 
11654bb1074Sjruoho 	for (a = 0; a < sizeof(long); ++a) {
11754bb1074Sjruoho 		for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
11854bb1074Sjruoho 
11954bb1074Sjruoho 			memcpy(&buf[a], tab[t].val, tab[t].len + 1);
12054bb1074Sjruoho 			len = strlen_fn(&buf[a]);
12154bb1074Sjruoho 
12254bb1074Sjruoho 			if (len != tab[t].len) {
12354bb1074Sjruoho 				/* Write error without using printf / strlen */
12454bb1074Sjruoho 				write(2, "alignment ", 10);
12554bb1074Sjruoho 				write_num(a);
12654bb1074Sjruoho 				write(2, ", test ", 7);
12754bb1074Sjruoho 				write_num(t);
12854bb1074Sjruoho 				write(2, ", got len ", 10);
12954bb1074Sjruoho 				write_num(len);
13054bb1074Sjruoho 				write(2, ", not ", 6);
13154bb1074Sjruoho 				write_num(tab[t].len);
13254bb1074Sjruoho 				write(2, ", for '", 7);
13354bb1074Sjruoho 				write(2, tab[t].val, tab[t].len);
13454bb1074Sjruoho 				write(2, "'\n", 2);
13554bb1074Sjruoho 				atf_tc_fail("See stderr for details");
13654bb1074Sjruoho 			}
13754bb1074Sjruoho 		}
13854bb1074Sjruoho 	}
139*cd517fb0Schristos 	(void)dlclose(dl_handle);
14054bb1074Sjruoho }
14154bb1074Sjruoho 
142b34acef4Sjruoho ATF_TC(strlen_huge);
ATF_TC_HEAD(strlen_huge,tc)143b34acef4Sjruoho ATF_TC_HEAD(strlen_huge, tc)
144b34acef4Sjruoho {
145b34acef4Sjruoho         atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings");
146b34acef4Sjruoho }
147b34acef4Sjruoho 
ATF_TC_BODY(strlen_huge,tc)148b34acef4Sjruoho ATF_TC_BODY(strlen_huge, tc)
149b34acef4Sjruoho {
150b34acef4Sjruoho 	long page;
151b34acef4Sjruoho 	char *str;
152b34acef4Sjruoho 	size_t i;
153b34acef4Sjruoho 
154b34acef4Sjruoho 	page = sysconf(_SC_PAGESIZE);
155b34acef4Sjruoho 	ATF_REQUIRE(page >= 0);
156b34acef4Sjruoho 
157b34acef4Sjruoho 	for (i = 1; i < 1000; i = i + 100) {
158b34acef4Sjruoho 
159b34acef4Sjruoho 		str = malloc(i * page + 1);
160b34acef4Sjruoho 
161b34acef4Sjruoho 		if (str == NULL)
162b34acef4Sjruoho 			continue;
163b34acef4Sjruoho 
164b34acef4Sjruoho 		(void)memset(str, 'x', i * page);
165247e3a69Snjoly 		str[i * page] = '\0';
166b34acef4Sjruoho 
167b34acef4Sjruoho 		ATF_REQUIRE(strlen(str) == i * page);
168b34acef4Sjruoho 		free(str);
169b34acef4Sjruoho 	}
170b34acef4Sjruoho }
171b34acef4Sjruoho 
1722b91d03eSjruoho ATF_TC(strnlen_basic);
ATF_TC_HEAD(strnlen_basic,tc)1732b91d03eSjruoho ATF_TC_HEAD(strnlen_basic, tc)
1742b91d03eSjruoho {
1752b91d03eSjruoho         atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)");
1762b91d03eSjruoho }
1772b91d03eSjruoho 
ATF_TC_BODY(strnlen_basic,tc)1782b91d03eSjruoho ATF_TC_BODY(strnlen_basic, tc)
1792b91d03eSjruoho {
1802b91d03eSjruoho 	char buf[1];
1812b91d03eSjruoho 
1822b91d03eSjruoho 	buf[0] = '\0';
1832b91d03eSjruoho 
18499db6ea6Sjruoho 	ATF_CHECK(strnlen(buf, 000) == 0);
18599db6ea6Sjruoho 	ATF_CHECK(strnlen(buf, 111) == 0);
1862b91d03eSjruoho 
18799db6ea6Sjruoho 	ATF_CHECK(strnlen("xxx", 0) == 0);
18899db6ea6Sjruoho 	ATF_CHECK(strnlen("xxx", 1) == 1);
18999db6ea6Sjruoho 	ATF_CHECK(strnlen("xxx", 2) == 2);
19099db6ea6Sjruoho 	ATF_CHECK(strnlen("xxx", 3) == 3);
19199db6ea6Sjruoho 	ATF_CHECK(strnlen("xxx", 9) == 3);
1922b91d03eSjruoho }
1932b91d03eSjruoho 
ATF_TP_ADD_TCS(tp)19454bb1074Sjruoho ATF_TP_ADD_TCS(tp)
19554bb1074Sjruoho {
19654bb1074Sjruoho 
19754bb1074Sjruoho 	ATF_TP_ADD_TC(tp, strlen_basic);
198b34acef4Sjruoho 	ATF_TP_ADD_TC(tp, strlen_huge);
1992b91d03eSjruoho 	ATF_TP_ADD_TC(tp, strnlen_basic);
20054bb1074Sjruoho 
20154bb1074Sjruoho 	return atf_no_error();
20254bb1074Sjruoho }
203