2 * Written by J.T. Conklin <jtc@acorntoolworks.com>
7 * str*() regression suite
9 * Trivial str*() implementations can be audited by hand. Optimized
10 * versions that unroll loops, use naturally-aligned memory acesses,
11 * and "magic" arithmetic sequences to detect zero-bytes, written in
12 * assembler are much harder to validate. This program attempts to
13 * catch the corner cases.
16 * Misssing checks for strncpy, strncat, strncmp, etc.
19 * Use mmap/mprotect to ensure the functions don't access memory
20 * across page boundaries.
22 * Consider generating tables programmatically. It would reduce
23 * the size, but it's also one more thing to go wrong.
25 * Share tables between strlen, strcpy, and strcat?
26 * Share tables between strchr and strrchr?
32 void check_strcmp(void);
37 /* try to trick the compiler */
38 int (*f
)(const char *, const char *s
) = strcmp
;
53 const struct tab tab
[] = {
74 { "aaaa", "aaaa", 0 },
75 { "aaaa", "aaab", -1 },
76 { "aaab", "aaaa", +1 },
77 { "aaa", "aaaa", -1 },
78 { "aaaa", "aaa", +1 },
80 { "aaaaa", "aaaaa", 0 },
81 { "aaaaa", "aaaab", -1 },
82 { "aaaab", "aaaaa", +1 },
83 { "aaaa", "aaaaa", -1 },
84 { "aaaaa", "aaaa", +1 },
86 { "aaaaaa", "aaaaaa", 0 },
87 { "aaaaaa", "aaaaab", -1 },
88 { "aaaaab", "aaaaaa", +1 },
89 { "aaaaa", "aaaaaa", -1 },
90 { "aaaaaa", "aaaaa", +1 },
93 for (a0
= 0; a0
< sizeof(long); ++a0
) {
94 for (a1
= 0; a1
< sizeof(long); ++a1
) {
95 for (t
= 0; t
< (sizeof(tab
) / sizeof(tab
[0])); ++t
) {
96 memcpy(&buf0
[a0
], tab
[t
].val0
, strlen(tab
[t
].val0
) + 1);
97 memcpy(&buf1
[a1
], tab
[t
].val1
, strlen(tab
[t
].val1
) + 1);
99 ret
= f(&buf0
[a0
], &buf1
[a1
]);
101 assert ((ret
== 0 && tab
[t
].ret
== 0) ||
102 (ret
< 0 && tab
[t
].ret
< 0) ||
103 (ret
> 0 && tab
[t
].ret
> 0));