t_strlen.c revision 1.6 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