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