1 1.6 christos /* $NetBSD: t_strlen.c,v 1.6 2017/01/14 20:49:24 christos 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.6 christos 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.6 christos dl_handle = dlopen(NULL, RTLD_LAZY); 112 1.6 christos 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.6 christos (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