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