diff --git a/lib/libc/tests/string/strncmp_test.c b/lib/libc/tests/string/strncmp_test.c --- a/lib/libc/tests/string/strncmp_test.c +++ b/lib/libc/tests/string/strncmp_test.c @@ -27,13 +27,61 @@ */ #include +#include +#include -#include +#include #include #include +#include + int (*volatile strncmp_fn)(const char *, const char *, size_t); +static char * +makebuf(size_t len, int guard_at_end) +{ + char *buf; + size_t alloc_size, page_size; + + page_size = getpagesize(); + alloc_size = roundup2(len, page_size) + page_size; + + buf = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + assert(buf); + if (guard_at_end) { + assert(munmap(buf + alloc_size - page_size, page_size) == 0); + return (buf + alloc_size - page_size - len); + } else { + assert(munmap(buf, page_size) == 0); + return (buf + page_size); + } +} + +static void +test_strncmp(const char *s) +{ + char *src, *dst; + size_t size, bufsize, x; + int i, j; + + size = strlen(s) + 1; + for (i = 0; i <= 1; i++) { + for (j = 0; j <= 1; j++) { + for (bufsize = 0; bufsize <= size + 10; bufsize++) { + src = makebuf(size, i); + memcpy(src, s, size); + dst = makebuf(bufsize, j); + memset(dst, 'X', bufsize); + assert(strlcpy(dst, src, bufsize) == size-1); + assert(bufsize == 0 || strncmp_fn(src, dst, bufsize - 1) == 0); + for (x = size; x < bufsize; x++) + assert(dst[x] == 'X'); + } + } + } +} + static void alignment_testcase(char *a, char *b, int want, size_t len) { @@ -138,6 +186,18 @@ check_strncmp_alignments(a, b, a_off, b_off, len, pos); } +ATF_TC_WITHOUT_HEAD(bounds); +ATF_TC_BODY(bounds, tc) +{ + size_t i; + char buf[64]; + + for (i = 0; i < sizeof(buf) - 1; i++) { + buf[i] = ' ' + i; + test_strncmp(buf); + } +} + ATF_TC(strncmp_null); ATF_TC_HEAD(strncmp_null, tc) { @@ -159,6 +219,7 @@ strncmp_fn = strncmp; ATF_TP_ADD_TC(tp, strncmp_alignments); + ATF_TP_ADD_TC(tp, bounds); ATF_TP_ADD_TC(tp, strncmp_null); return atf_no_error();