1314817Sngie/* $NetBSD: t_strlen.c,v 1.6 2017/01/14 20:49:24 christos Exp $ */ 2272343Sngie 3272343Sngie/* 4272343Sngie * Written by J.T. Conklin <jtc@acorntoolworks.com> 5272343Sngie * Public domain. 6272343Sngie */ 7272343Sngie 8272343Sngie#include <atf-c.h> 9272343Sngie#include <string.h> 10272343Sngie#include <unistd.h> 11272343Sngie#include <stdio.h> 12272343Sngie#include <stdlib.h> 13272343Sngie#include <dlfcn.h> 14272343Sngie#include <unistd.h> 15272343Sngie 16272343Sngiestatic void write_num(int); 17272343Sngie 18272343Sngiestatic void 19272343Sngiewrite_num(int val) 20272343Sngie{ 21272343Sngie char buf[20]; 22272343Sngie int i; 23272343Sngie 24272343Sngie for (i = sizeof buf; --i >= 0;) { 25272343Sngie buf[i] = '0' + val % 10; 26272343Sngie val /= 10; 27272343Sngie if (val == 0) { 28272343Sngie write(2, buf + i, sizeof buf - i); 29272343Sngie return; 30272343Sngie } 31272343Sngie } 32272343Sngie write(2, "overflow", 8); 33272343Sngie} 34272343Sngie 35272343SngieATF_TC(strlen_basic); 36272343SngieATF_TC_HEAD(strlen_basic, tc) 37272343Sngie{ 38272343Sngie atf_tc_set_md_var(tc, "descr", "Test strlen(3) results"); 39272343Sngie} 40272343Sngie 41272343SngieATF_TC_BODY(strlen_basic, tc) 42272343Sngie{ 43311611Sngie void *dl_handle; 44272343Sngie /* try to trick the compiler */ 45272343Sngie size_t (*strlen_fn)(const char *); 46272343Sngie 47272343Sngie unsigned int a, t; 48272343Sngie size_t len; 49272343Sngie char buf[64]; 50272343Sngie 51272343Sngie struct tab { 52272343Sngie const char* val; 53272343Sngie size_t len; 54272343Sngie }; 55272343Sngie 56272343Sngie const struct tab tab[] = { 57272343Sngie /* 58272343Sngie * patterns that check for all combinations of leading and 59272343Sngie * trailing unaligned characters (on a 64 bit processor) 60272343Sngie */ 61272343Sngie 62272343Sngie { "", 0 }, 63272343Sngie { "a", 1 }, 64272343Sngie { "ab", 2 }, 65272343Sngie { "abc", 3 }, 66272343Sngie { "abcd", 4 }, 67272343Sngie { "abcde", 5 }, 68272343Sngie { "abcdef", 6 }, 69272343Sngie { "abcdefg", 7 }, 70272343Sngie { "abcdefgh", 8 }, 71272343Sngie { "abcdefghi", 9 }, 72272343Sngie { "abcdefghij", 10 }, 73272343Sngie { "abcdefghijk", 11 }, 74272343Sngie { "abcdefghijkl", 12 }, 75272343Sngie { "abcdefghijklm", 13 }, 76272343Sngie { "abcdefghijklmn", 14 }, 77272343Sngie { "abcdefghijklmno", 15 }, 78272343Sngie { "abcdefghijklmnop", 16 }, 79272343Sngie { "abcdefghijklmnopq", 17 }, 80272343Sngie { "abcdefghijklmnopqr", 18 }, 81272343Sngie { "abcdefghijklmnopqrs", 19 }, 82272343Sngie { "abcdefghijklmnopqrst", 20 }, 83272343Sngie { "abcdefghijklmnopqrstu", 21 }, 84272343Sngie { "abcdefghijklmnopqrstuv", 22 }, 85272343Sngie { "abcdefghijklmnopqrstuvw", 23 }, 86272343Sngie 87272343Sngie /* 88272343Sngie * patterns that check for the cases where the expression: 89272343Sngie * 90272343Sngie * ((word - 0x7f7f..7f) & 0x8080..80) 91272343Sngie * 92272343Sngie * returns non-zero even though there are no zero bytes in 93272343Sngie * the word. 94272343Sngie */ 95272343Sngie 96272343Sngie { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, 97272343Sngie { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, 98272343Sngie { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, 99272343Sngie { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, 100272343Sngie { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, 101272343Sngie { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, 102272343Sngie { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, 103272343Sngie { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, 104272343Sngie { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, 105272343Sngie }; 106272343Sngie 107272343Sngie /* 108272343Sngie * During testing it is useful have the rest of the program 109272343Sngie * use a known good version! 110272343Sngie */ 111311611Sngie dl_handle = dlopen(NULL, RTLD_LAZY); 112311611Sngie strlen_fn = dlsym(dl_handle, "test_strlen"); 113272343Sngie if (!strlen_fn) 114272343Sngie strlen_fn = strlen; 115272343Sngie 116272343Sngie for (a = 0; a < sizeof(long); ++a) { 117272343Sngie for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { 118272343Sngie 119272343Sngie memcpy(&buf[a], tab[t].val, tab[t].len + 1); 120272343Sngie len = strlen_fn(&buf[a]); 121272343Sngie 122272343Sngie if (len != tab[t].len) { 123272343Sngie /* Write error without using printf / strlen */ 124272343Sngie write(2, "alignment ", 10); 125272343Sngie write_num(a); 126272343Sngie write(2, ", test ", 7); 127272343Sngie write_num(t); 128272343Sngie write(2, ", got len ", 10); 129272343Sngie write_num(len); 130272343Sngie write(2, ", not ", 6); 131272343Sngie write_num(tab[t].len); 132272343Sngie write(2, ", for '", 7); 133272343Sngie write(2, tab[t].val, tab[t].len); 134272343Sngie write(2, "'\n", 2); 135272343Sngie atf_tc_fail("See stderr for details"); 136272343Sngie } 137272343Sngie } 138272343Sngie } 139311611Sngie (void)dlclose(dl_handle); 140272343Sngie} 141272343Sngie 142272343SngieATF_TC(strlen_huge); 143272343SngieATF_TC_HEAD(strlen_huge, tc) 144272343Sngie{ 145272343Sngie atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings"); 146272343Sngie} 147272343Sngie 148272343SngieATF_TC_BODY(strlen_huge, tc) 149272343Sngie{ 150272343Sngie long page; 151272343Sngie char *str; 152272343Sngie size_t i; 153272343Sngie 154272343Sngie page = sysconf(_SC_PAGESIZE); 155272343Sngie ATF_REQUIRE(page >= 0); 156272343Sngie 157272343Sngie for (i = 1; i < 1000; i = i + 100) { 158272343Sngie 159272343Sngie str = malloc(i * page + 1); 160272343Sngie 161272343Sngie if (str == NULL) 162272343Sngie continue; 163272343Sngie 164272343Sngie (void)memset(str, 'x', i * page); 165272343Sngie str[i * page] = '\0'; 166272343Sngie 167272343Sngie ATF_REQUIRE(strlen(str) == i * page); 168272343Sngie free(str); 169272343Sngie } 170272343Sngie} 171272343Sngie 172272343SngieATF_TC(strnlen_basic); 173272343SngieATF_TC_HEAD(strnlen_basic, tc) 174272343Sngie{ 175272343Sngie atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)"); 176272343Sngie} 177272343Sngie 178272343SngieATF_TC_BODY(strnlen_basic, tc) 179272343Sngie{ 180272343Sngie char buf[1]; 181272343Sngie 182272343Sngie buf[0] = '\0'; 183272343Sngie 184272343Sngie ATF_CHECK(strnlen(buf, 000) == 0); 185272343Sngie ATF_CHECK(strnlen(buf, 111) == 0); 186272343Sngie 187272343Sngie ATF_CHECK(strnlen("xxx", 0) == 0); 188272343Sngie ATF_CHECK(strnlen("xxx", 1) == 1); 189272343Sngie ATF_CHECK(strnlen("xxx", 2) == 2); 190272343Sngie ATF_CHECK(strnlen("xxx", 3) == 3); 191272343Sngie ATF_CHECK(strnlen("xxx", 9) == 3); 192272343Sngie} 193272343Sngie 194272343SngieATF_TP_ADD_TCS(tp) 195272343Sngie{ 196272343Sngie 197272343Sngie ATF_TP_ADD_TC(tp, strlen_basic); 198272343Sngie ATF_TP_ADD_TC(tp, strlen_huge); 199272343Sngie ATF_TP_ADD_TC(tp, strnlen_basic); 200272343Sngie 201272343Sngie return atf_no_error(); 202272343Sngie} 203