1 /* $NetBSD: t_strchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ 2 3 /* 4 * Written by J.T. Conklin <jtc@acorntoolworks.com> 5 * Public domain. 6 */ 7 8 #include <atf-c.h> 9 #include <string.h> 10 #include <unistd.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <dlfcn.h> 14 15 static char *slow_strchr(char *, int); 16 static void verify_strchr(char *, int, unsigned int, unsigned int); 17 18 char * (*volatile strchr_fn)(const char *, int); 19 20 static char * 21 slow_strchr(char *buf, int ch) 22 { 23 unsigned char c = 1; 24 25 ch &= 0xff; 26 27 for (; c != 0; buf++) { 28 c = *buf; 29 if (c == ch) 30 return buf; 31 } 32 return 0; 33 } 34 35 static void 36 verify_strchr(char *buf, int ch, unsigned int t, unsigned int a) 37 { 38 const char *off, *ok_off; 39 40 off = strchr_fn(buf, ch); 41 ok_off = slow_strchr(buf, ch); 42 if (off == ok_off) 43 return; 44 45 fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, " 46 "alignment %d)\n", 47 buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a); 48 49 atf_tc_fail("Check stderr for details"); 50 } 51 52 ATF_TC(strchr_basic); 53 ATF_TC_HEAD(strchr_basic, tc) 54 { 55 56 atf_tc_set_md_var(tc, "descr", "Test strchr(3) results"); 57 } 58 59 ATF_TC_BODY(strchr_basic, tc) 60 { 61 #ifdef __FreeBSD__ 62 void *dl_handle; 63 #endif 64 unsigned int t, a; 65 char *off; 66 char buf[32]; 67 68 const char *tab[] = { 69 "", 70 "a", 71 "aa", 72 "abc", 73 "abcd", 74 "abcde", 75 "abcdef", 76 "abcdefg", 77 "abcdefgh", 78 79 "/", 80 "//", 81 "/a", 82 "/a/", 83 "/ab", 84 "/ab/", 85 "/abc", 86 "/abc/", 87 "/abcd", 88 "/abcd/", 89 "/abcde", 90 "/abcde/", 91 "/abcdef", 92 "/abcdef/", 93 "/abcdefg", 94 "/abcdefg/", 95 "/abcdefgh", 96 "/abcdefgh/", 97 98 "a/", 99 "a//", 100 "a/a", 101 "a/a/", 102 "a/ab", 103 "a/ab/", 104 "a/abc", 105 "a/abc/", 106 "a/abcd", 107 "a/abcd/", 108 "a/abcde", 109 "a/abcde/", 110 "a/abcdef", 111 "a/abcdef/", 112 "a/abcdefg", 113 "a/abcdefg/", 114 "a/abcdefgh", 115 "a/abcdefgh/", 116 117 "ab/", 118 "ab//", 119 "ab/a", 120 "ab/a/", 121 "ab/ab", 122 "ab/ab/", 123 "ab/abc", 124 "ab/abc/", 125 "ab/abcd", 126 "ab/abcd/", 127 "ab/abcde", 128 "ab/abcde/", 129 "ab/abcdef", 130 "ab/abcdef/", 131 "ab/abcdefg", 132 "ab/abcdefg/", 133 "ab/abcdefgh", 134 "ab/abcdefgh/", 135 136 "abc/", 137 "abc//", 138 "abc/a", 139 "abc/a/", 140 "abc/ab", 141 "abc/ab/", 142 "abc/abc", 143 "abc/abc/", 144 "abc/abcd", 145 "abc/abcd/", 146 "abc/abcde", 147 "abc/abcde/", 148 "abc/abcdef", 149 "abc/abcdef/", 150 "abc/abcdefg", 151 "abc/abcdefg/", 152 "abc/abcdefgh", 153 "abc/abcdefgh/", 154 155 "abcd/", 156 "abcd//", 157 "abcd/a", 158 "abcd/a/", 159 "abcd/ab", 160 "abcd/ab/", 161 "abcd/abc", 162 "abcd/abc/", 163 "abcd/abcd", 164 "abcd/abcd/", 165 "abcd/abcde", 166 "abcd/abcde/", 167 "abcd/abcdef", 168 "abcd/abcdef/", 169 "abcd/abcdefg", 170 "abcd/abcdefg/", 171 "abcd/abcdefgh", 172 "abcd/abcdefgh/", 173 174 "abcde/", 175 "abcde//", 176 "abcde/a", 177 "abcde/a/", 178 "abcde/ab", 179 "abcde/ab/", 180 "abcde/abc", 181 "abcde/abc/", 182 "abcde/abcd", 183 "abcde/abcd/", 184 "abcde/abcde", 185 "abcde/abcde/", 186 "abcde/abcdef", 187 "abcde/abcdef/", 188 "abcde/abcdefg", 189 "abcde/abcdefg/", 190 "abcde/abcdefgh", 191 "abcde/abcdefgh/", 192 193 "abcdef/", 194 "abcdef//", 195 "abcdef/a", 196 "abcdef/a/", 197 "abcdef/ab", 198 "abcdef/ab/", 199 "abcdef/abc", 200 "abcdef/abc/", 201 "abcdef/abcd", 202 "abcdef/abcd/", 203 "abcdef/abcde", 204 "abcdef/abcde/", 205 "abcdef/abcdef", 206 "abcdef/abcdef/", 207 "abcdef/abcdefg", 208 "abcdef/abcdefg/", 209 "abcdef/abcdefgh", 210 "abcdef/abcdefgh/", 211 212 "abcdefg/", 213 "abcdefg//", 214 "abcdefg/a", 215 "abcdefg/a/", 216 "abcdefg/ab", 217 "abcdefg/ab/", 218 "abcdefg/abc", 219 "abcdefg/abc/", 220 "abcdefg/abcd", 221 "abcdefg/abcd/", 222 "abcdefg/abcde", 223 "abcdefg/abcde/", 224 "abcdefg/abcdef", 225 "abcdefg/abcdef/", 226 "abcdefg/abcdefg", 227 "abcdefg/abcdefg/", 228 "abcdefg/abcdefgh", 229 "abcdefg/abcdefgh/", 230 231 "abcdefgh/", 232 "abcdefgh//", 233 "abcdefgh/a", 234 "abcdefgh/a/", 235 "abcdefgh/ab", 236 "abcdefgh/ab/", 237 "abcdefgh/abc", 238 "abcdefgh/abc/", 239 "abcdefgh/abcd", 240 "abcdefgh/abcd/", 241 "abcdefgh/abcde", 242 "abcdefgh/abcde/", 243 "abcdefgh/abcdef", 244 "abcdefgh/abcdef/", 245 "abcdefgh/abcdefg", 246 "abcdefgh/abcdefg/", 247 "abcdefgh/abcdefgh", 248 "abcdefgh/abcdefgh/", 249 }; 250 251 #ifdef __FreeBSD__ 252 dl_handle = dlopen(NULL, RTLD_LAZY); 253 strchr_fn = dlsym(dl_handle, "test_strlen"); 254 #else 255 strchr_fn = dlsym(dlopen(0, RTLD_LAZY), "test_strchr"); 256 #endif 257 if (!strchr_fn) 258 strchr_fn = strchr; 259 260 for (a = 3; a < 3 + sizeof(long); ++a) { 261 /* Put char and a \0 before the buffer */ 262 buf[a-1] = '/'; 263 buf[a-2] = '0'; 264 buf[a-3] = 0xff; 265 for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { 266 int len = strlen(tab[t]) + 1; 267 memcpy(&buf[a], tab[t], len); 268 269 /* Put the char we are looking for after the \0 */ 270 buf[a + len] = '/'; 271 272 /* Check search for NUL at end of string */ 273 verify_strchr(buf + a, 0, t, a); 274 275 /* Then for the '/' in the strings */ 276 verify_strchr(buf + a, '/', t, a); 277 278 /* check zero extension of char arg */ 279 verify_strchr(buf + a, 0xffffff00 | '/', t, a); 280 281 /* Replace all the '/' with 0xff */ 282 while ((off = slow_strchr(buf + a, '/')) != NULL) 283 *off = 0xff; 284 285 buf[a + len] = 0xff; 286 287 /* Check we can search for 0xff as well as '/' */ 288 verify_strchr(buf + a, 0xff, t, a); 289 } 290 } 291 #ifdef __FreeBSD__ 292 (void)dlclose(dl_handle); 293 #endif 294 } 295 296 ATF_TP_ADD_TCS(tp) 297 { 298 299 ATF_TP_ADD_TC(tp, strchr_basic); 300 301 return atf_no_error(); 302 } 303