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