diff --git a/lib/libc/tests/string/Makefile b/lib/libc/tests/string/Makefile index f46076619352..a019939c30af 100644 --- a/lib/libc/tests/string/Makefile +++ b/lib/libc/tests/string/Makefile @@ -1,57 +1,58 @@ # ensure libc functions are tested, not clang's builtins CFLAGS+= -fno-builtin ATF_TESTS_C+= bcmp_test ATF_TESTS_C+= ffs_test ATF_TESTS_C+= ffsl_test ATF_TESTS_C+= ffsll_test ATF_TESTS_C+= fls_test ATF_TESTS_C+= flsl_test ATF_TESTS_C+= flsll_test ATF_TESTS_C+= memccpy_test ATF_TESTS_C+= memcmp_test ATF_TESTS_C+= memrchr_test ATF_TESTS_C+= memset2_test ATF_TESTS_C+= memset_s_test ATF_TESTS_C+= strncmp_test ATF_TESTS_C+= stpncpy_test +ATF_TESTS_C+= strnlen_test ATF_TESTS_C+= strcmp2_test ATF_TESTS_C+= strcspn_test ATF_TESTS_C+= strerror2_test ATF_TESTS_C+= strlcpy_test ATF_TESTS_C+= strspn_test ATF_TESTS_C+= strverscmp_test ATF_TESTS_C+= strxfrm_test ATF_TESTS_C+= timingsafe_bcmp_test ATF_TESTS_C+= timingsafe_memcmp_test ATF_TESTS_C+= wcscasecmp_test ATF_TESTS_C+= wcscoll_test ATF_TESTS_C+= wcsnlen_test # TODO: popcount, stresep NETBSD_ATF_TESTS_C+= memchr_test NETBSD_ATF_TESTS_C+= memcpy_test NETBSD_ATF_TESTS_C+= memmem_test NETBSD_ATF_TESTS_C+= memset_test NETBSD_ATF_TESTS_C+= strcat_test NETBSD_ATF_TESTS_C+= strchr_test NETBSD_ATF_TESTS_C+= strchrnul_test NETBSD_ATF_TESTS_C+= strcmp_test NETBSD_ATF_TESTS_C+= strcpy_test NETBSD_ATF_TESTS_C+= strerror_test NETBSD_ATF_TESTS_C+= strlen_test NETBSD_ATF_TESTS_C+= strpbrk_test NETBSD_ATF_TESTS_C+= strrchr_test NETBSD_ATF_TESTS_C+= swab_test SRCS.memset2_test= memset_test.c SRCS.strcmp2_test= strcmp_test.c SRCS.strerror2_test= strerror_test.c .include "../Makefile.netbsd-tests" LIBADD.memchr_test+= md LIBADD.memcpy_test+= md .include diff --git a/lib/libc/tests/string/strnlen_test.c b/lib/libc/tests/string/strnlen_test.c new file mode 100644 index 000000000000..31c2384bb30f --- /dev/null +++ b/lib/libc/tests/string/strnlen_test.c @@ -0,0 +1,141 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Strahinja Stanisic + */ + +#include +#include +#include +#include +#include +#include + +#include + +ATF_TC(strnlen_alignments); +ATF_TC_HEAD(strnlen_alignments, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strnlen(3) with different alignments"); +} + +ATF_TC_BODY(strnlen_alignments, tc) +{ + size_t (*strnlen_fn)(const char*, size_t) = strnlen; + char alignas(16) buffer[1 + 16 + 64 + 1 + 1]; + + memset(buffer, '/', sizeof(buffer)); + + for (int align = 1; align < 1 + 16; align++) { + char *s = buffer + align; + + for (size_t maxlen = 0; maxlen <= 64; maxlen++) { + for (size_t len = 0; len <= maxlen; len++) { + /* returns length */ + + /* without sentinels */ + s[len] = '\0'; + size_t val = strnlen_fn(s, maxlen); + if (val != len) { + fprintf(stderr, "align = %d, maxlen = %zu, len = %zu", + align, maxlen, len); + atf_tc_fail("returned incorrect len"); + } + + /* with sentinels */ + s[-1] = '\0'; + s[maxlen + 1] = '\0'; + val = strnlen_fn(s, maxlen); + if (val != len) { + fprintf(stderr, "align = %d, maxlen = %zu, len = %zu", + align, maxlen, len); + atf_tc_fail("returned incorrect len (sentinels)"); + } + + /* cleanup */ + s[-1] = '/'; + s[len] = '/'; + s[maxlen + 1] = '/'; + + } + + /* returns maxlen */ + + /* without sentinels */ + size_t val = strnlen_fn(s, maxlen); + if (val != maxlen) { + fprintf(stderr, "align = %d, maxlen = %zu", + align, maxlen); + atf_tc_fail("should return maxlen"); + } + + /* with sentinels */ + s[-1] = '\0'; + s[maxlen + 1] = '\0'; + val = strnlen_fn(s, maxlen); + if (val != maxlen) { + fprintf(stderr, "align = %d, maxlen = %zu", + align, maxlen); + atf_tc_fail("should return maxlen (sentinels)"); + } + + /* cleanup */ + s[-1] = '/'; + s[maxlen + 1] = '/'; + } + } +} + +ATF_TC(strnlen_size_max); +ATF_TC_HEAD(strnlen_size_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strnlen(3) with maxlen=SIZE_MAX"); +} + +ATF_TC_BODY(strnlen_size_max, tc) +{ + size_t (*strnlen_fn)(const char*, size_t) = strnlen; + char alignas(16) buffer[1 + 16 + 64 + 1 + 1]; + + memset(buffer, '/', sizeof(buffer)); + + for (int align = 1; align < 1 + 16; align++) { + char* s = buffer + align; + + for (size_t len = 0; len <= 64; len++) { + /* returns length */ + + /* without sentinels */ + s[len] = '\0'; + size_t val = strnlen_fn(s, SIZE_MAX); + if (val != len) { + fprintf(stderr, "align = %d, maxlen = %zu, len = %zu", + align, SIZE_MAX, len); + atf_tc_fail("returned incorrect len (SIZE_MAX)"); + } + + /* with sentinels */ + s[-1] = '\0'; + val = strnlen_fn(s, SIZE_MAX); + if (val != len) { + fprintf(stderr, "align = %d, maxlen = %zu, len = %zu", + align, SIZE_MAX, len); + atf_tc_fail("returned incorrect len (sentinels) (SIZE_MAX)"); + } + + /* cleanup */ + s[-1] = '/'; + s[len] = '/'; + } + } +} + + + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, strnlen_alignments); + ATF_TP_ADD_TC(tp, strnlen_size_max); + + return atf_no_error(); +}