157718be8SEnji Cooper /* $NetBSD: t_strlen.c,v 1.5 2011/07/14 07:33:20 jruoho Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper /* 457718be8SEnji Cooper * Written by J.T. Conklin <jtc@acorntoolworks.com> 557718be8SEnji Cooper * Public domain. 657718be8SEnji Cooper */ 757718be8SEnji Cooper 857718be8SEnji Cooper #include <atf-c.h> 957718be8SEnji Cooper #include <string.h> 1057718be8SEnji Cooper #include <unistd.h> 1157718be8SEnji Cooper #include <stdio.h> 1257718be8SEnji Cooper #include <stdlib.h> 1357718be8SEnji Cooper #include <dlfcn.h> 1457718be8SEnji Cooper #include <unistd.h> 1557718be8SEnji Cooper 1657718be8SEnji Cooper static void write_num(int); 1757718be8SEnji Cooper 1857718be8SEnji Cooper static void 1957718be8SEnji Cooper write_num(int val) 2057718be8SEnji Cooper { 2157718be8SEnji Cooper char buf[20]; 2257718be8SEnji Cooper int i; 2357718be8SEnji Cooper 2457718be8SEnji Cooper for (i = sizeof buf; --i >= 0;) { 2557718be8SEnji Cooper buf[i] = '0' + val % 10; 2657718be8SEnji Cooper val /= 10; 2757718be8SEnji Cooper if (val == 0) { 2857718be8SEnji Cooper write(2, buf + i, sizeof buf - i); 2957718be8SEnji Cooper return; 3057718be8SEnji Cooper } 3157718be8SEnji Cooper } 3257718be8SEnji Cooper write(2, "overflow", 8); 3357718be8SEnji Cooper } 3457718be8SEnji Cooper 3557718be8SEnji Cooper ATF_TC(strlen_basic); 3657718be8SEnji Cooper ATF_TC_HEAD(strlen_basic, tc) 3757718be8SEnji Cooper { 3857718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strlen(3) results"); 3957718be8SEnji Cooper } 4057718be8SEnji Cooper 4157718be8SEnji Cooper ATF_TC_BODY(strlen_basic, tc) 4257718be8SEnji Cooper { 43*83e8b13fSEnji Cooper #ifdef __FreeBSD__ 44*83e8b13fSEnji Cooper void *dl_handle; 45*83e8b13fSEnji Cooper #endif 4657718be8SEnji Cooper /* try to trick the compiler */ 4757718be8SEnji Cooper size_t (*strlen_fn)(const char *); 4857718be8SEnji Cooper 4957718be8SEnji Cooper unsigned int a, t; 5057718be8SEnji Cooper size_t len; 5157718be8SEnji Cooper char buf[64]; 5257718be8SEnji Cooper 5357718be8SEnji Cooper struct tab { 5457718be8SEnji Cooper const char* val; 5557718be8SEnji Cooper size_t len; 5657718be8SEnji Cooper }; 5757718be8SEnji Cooper 5857718be8SEnji Cooper const struct tab tab[] = { 5957718be8SEnji Cooper /* 6057718be8SEnji Cooper * patterns that check for all combinations of leading and 6157718be8SEnji Cooper * trailing unaligned characters (on a 64 bit processor) 6257718be8SEnji Cooper */ 6357718be8SEnji Cooper 6457718be8SEnji Cooper { "", 0 }, 6557718be8SEnji Cooper { "a", 1 }, 6657718be8SEnji Cooper { "ab", 2 }, 6757718be8SEnji Cooper { "abc", 3 }, 6857718be8SEnji Cooper { "abcd", 4 }, 6957718be8SEnji Cooper { "abcde", 5 }, 7057718be8SEnji Cooper { "abcdef", 6 }, 7157718be8SEnji Cooper { "abcdefg", 7 }, 7257718be8SEnji Cooper { "abcdefgh", 8 }, 7357718be8SEnji Cooper { "abcdefghi", 9 }, 7457718be8SEnji Cooper { "abcdefghij", 10 }, 7557718be8SEnji Cooper { "abcdefghijk", 11 }, 7657718be8SEnji Cooper { "abcdefghijkl", 12 }, 7757718be8SEnji Cooper { "abcdefghijklm", 13 }, 7857718be8SEnji Cooper { "abcdefghijklmn", 14 }, 7957718be8SEnji Cooper { "abcdefghijklmno", 15 }, 8057718be8SEnji Cooper { "abcdefghijklmnop", 16 }, 8157718be8SEnji Cooper { "abcdefghijklmnopq", 17 }, 8257718be8SEnji Cooper { "abcdefghijklmnopqr", 18 }, 8357718be8SEnji Cooper { "abcdefghijklmnopqrs", 19 }, 8457718be8SEnji Cooper { "abcdefghijklmnopqrst", 20 }, 8557718be8SEnji Cooper { "abcdefghijklmnopqrstu", 21 }, 8657718be8SEnji Cooper { "abcdefghijklmnopqrstuv", 22 }, 8757718be8SEnji Cooper { "abcdefghijklmnopqrstuvw", 23 }, 8857718be8SEnji Cooper 8957718be8SEnji Cooper /* 9057718be8SEnji Cooper * patterns that check for the cases where the expression: 9157718be8SEnji Cooper * 9257718be8SEnji Cooper * ((word - 0x7f7f..7f) & 0x8080..80) 9357718be8SEnji Cooper * 9457718be8SEnji Cooper * returns non-zero even though there are no zero bytes in 9557718be8SEnji Cooper * the word. 9657718be8SEnji Cooper */ 9757718be8SEnji Cooper 9857718be8SEnji Cooper { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, 9957718be8SEnji Cooper { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, 10057718be8SEnji Cooper { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, 10157718be8SEnji Cooper { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, 10257718be8SEnji Cooper { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, 10357718be8SEnji Cooper { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, 10457718be8SEnji Cooper { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, 10557718be8SEnji Cooper { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, 10657718be8SEnji Cooper { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, 10757718be8SEnji Cooper }; 10857718be8SEnji Cooper 10957718be8SEnji Cooper /* 11057718be8SEnji Cooper * During testing it is useful have the rest of the program 11157718be8SEnji Cooper * use a known good version! 11257718be8SEnji Cooper */ 113*83e8b13fSEnji Cooper #ifdef __FreeBSD__ 114*83e8b13fSEnji Cooper dl_handle = dlopen(NULL, RTLD_LAZY); 115*83e8b13fSEnji Cooper strlen_fn = dlsym(dl_handle, "test_strlen"); 116*83e8b13fSEnji Cooper #else 11757718be8SEnji Cooper strlen_fn = dlsym(dlopen(NULL, RTLD_LAZY), "test_strlen"); 118*83e8b13fSEnji Cooper #endif 11957718be8SEnji Cooper if (!strlen_fn) 12057718be8SEnji Cooper strlen_fn = strlen; 12157718be8SEnji Cooper 12257718be8SEnji Cooper for (a = 0; a < sizeof(long); ++a) { 12357718be8SEnji Cooper for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { 12457718be8SEnji Cooper 12557718be8SEnji Cooper memcpy(&buf[a], tab[t].val, tab[t].len + 1); 12657718be8SEnji Cooper len = strlen_fn(&buf[a]); 12757718be8SEnji Cooper 12857718be8SEnji Cooper if (len != tab[t].len) { 12957718be8SEnji Cooper /* Write error without using printf / strlen */ 13057718be8SEnji Cooper write(2, "alignment ", 10); 13157718be8SEnji Cooper write_num(a); 13257718be8SEnji Cooper write(2, ", test ", 7); 13357718be8SEnji Cooper write_num(t); 13457718be8SEnji Cooper write(2, ", got len ", 10); 13557718be8SEnji Cooper write_num(len); 13657718be8SEnji Cooper write(2, ", not ", 6); 13757718be8SEnji Cooper write_num(tab[t].len); 13857718be8SEnji Cooper write(2, ", for '", 7); 13957718be8SEnji Cooper write(2, tab[t].val, tab[t].len); 14057718be8SEnji Cooper write(2, "'\n", 2); 14157718be8SEnji Cooper atf_tc_fail("See stderr for details"); 14257718be8SEnji Cooper } 14357718be8SEnji Cooper } 14457718be8SEnji Cooper } 145*83e8b13fSEnji Cooper #ifdef __FreeBSD__ 146*83e8b13fSEnji Cooper (void)dlclose(dl_handle); 147*83e8b13fSEnji Cooper #endif 14857718be8SEnji Cooper } 14957718be8SEnji Cooper 15057718be8SEnji Cooper ATF_TC(strlen_huge); 15157718be8SEnji Cooper ATF_TC_HEAD(strlen_huge, tc) 15257718be8SEnji Cooper { 15357718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings"); 15457718be8SEnji Cooper } 15557718be8SEnji Cooper 15657718be8SEnji Cooper ATF_TC_BODY(strlen_huge, tc) 15757718be8SEnji Cooper { 15857718be8SEnji Cooper long page; 15957718be8SEnji Cooper char *str; 16057718be8SEnji Cooper size_t i; 16157718be8SEnji Cooper 16257718be8SEnji Cooper page = sysconf(_SC_PAGESIZE); 16357718be8SEnji Cooper ATF_REQUIRE(page >= 0); 16457718be8SEnji Cooper 16557718be8SEnji Cooper for (i = 1; i < 1000; i = i + 100) { 16657718be8SEnji Cooper 16757718be8SEnji Cooper str = malloc(i * page + 1); 16857718be8SEnji Cooper 16957718be8SEnji Cooper if (str == NULL) 17057718be8SEnji Cooper continue; 17157718be8SEnji Cooper 17257718be8SEnji Cooper (void)memset(str, 'x', i * page); 17357718be8SEnji Cooper str[i * page] = '\0'; 17457718be8SEnji Cooper 17557718be8SEnji Cooper ATF_REQUIRE(strlen(str) == i * page); 17657718be8SEnji Cooper free(str); 17757718be8SEnji Cooper } 17857718be8SEnji Cooper } 17957718be8SEnji Cooper 18057718be8SEnji Cooper ATF_TC(strnlen_basic); 18157718be8SEnji Cooper ATF_TC_HEAD(strnlen_basic, tc) 18257718be8SEnji Cooper { 18357718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)"); 18457718be8SEnji Cooper } 18557718be8SEnji Cooper 18657718be8SEnji Cooper ATF_TC_BODY(strnlen_basic, tc) 18757718be8SEnji Cooper { 18857718be8SEnji Cooper char buf[1]; 18957718be8SEnji Cooper 19057718be8SEnji Cooper buf[0] = '\0'; 19157718be8SEnji Cooper 19257718be8SEnji Cooper ATF_CHECK(strnlen(buf, 000) == 0); 19357718be8SEnji Cooper ATF_CHECK(strnlen(buf, 111) == 0); 19457718be8SEnji Cooper 19557718be8SEnji Cooper ATF_CHECK(strnlen("xxx", 0) == 0); 19657718be8SEnji Cooper ATF_CHECK(strnlen("xxx", 1) == 1); 19757718be8SEnji Cooper ATF_CHECK(strnlen("xxx", 2) == 2); 19857718be8SEnji Cooper ATF_CHECK(strnlen("xxx", 3) == 3); 19957718be8SEnji Cooper ATF_CHECK(strnlen("xxx", 9) == 3); 20057718be8SEnji Cooper } 20157718be8SEnji Cooper 20257718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 20357718be8SEnji Cooper { 20457718be8SEnji Cooper 20557718be8SEnji Cooper ATF_TP_ADD_TC(tp, strlen_basic); 20657718be8SEnji Cooper ATF_TP_ADD_TC(tp, strlen_huge); 20757718be8SEnji Cooper ATF_TP_ADD_TC(tp, strnlen_basic); 20857718be8SEnji Cooper 20957718be8SEnji Cooper return atf_no_error(); 21057718be8SEnji Cooper } 211