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