From e7c86620bb0c0f8b868d3e4c8dcdebeeffb99631 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Mon, 4 May 2026 17:02:12 +0200 Subject: Add a handful of tests --- tests/Makefile | 23 +++++++++++++++++++++++ tests/test_confstr_static.c | 16 ++++++++++++++++ tests/test_mbsnrtowcs_dynamic.c | 2 +- tests/test_mbsnrtowcs_static.c | 2 +- tests/test_mbsrtowcs_dynamic.c | 24 ++++++++++++++++++++++++ tests/test_mbsrtowcs_static.c | 24 ++++++++++++++++++++++++ tests/test_mbstowcs_dynamic.c | 16 ++++++++++++++++ tests/test_mbstowcs_static.c | 16 ++++++++++++++++ tests/test_memcpy_overlap.c | 27 +++++++++++++++++++++++++++ tests/test_pread_dynamic.c | 16 ++++++++++++++++ tests/test_pread_static.c | 16 ++++++++++++++++ tests/test_readlinkat_dynamic.c | 17 +++++++++++++++++ tests/test_readlinkat_static.c | 17 +++++++++++++++++ tests/test_select_dynamic.c | 16 ---------------- tests/test_select_static.c | 16 ---------------- tests/test_snprintf_dynamic.c | 18 ++++++++++++++++++ tests/test_snprintf_static.c | 18 ++++++++++++++++++ tests/test_strcat_dynamic_write.c | 15 +++++++++++++++ tests/test_wcscat_dynamic_write.c | 21 +++++++++++++++++++++ tests/test_wcscpy_dynamic_write.c | 22 ++++++++++++++++++++++ tests/test_wcsncat_dynamic_write.c | 16 ++++++++++++++++ tests/test_wcsncpy_dynamic_write.c | 16 ++++++++++++++++ tests/test_wcsnrtombs_dynamic.c | 2 +- tests/test_wcsnrtombs_static.c | 2 +- tests/test_wcsrtombs_dynamic.c | 24 ++++++++++++++++++++++++ tests/test_wcsrtombs_static.c | 24 ++++++++++++++++++++++++ tests/test_wcstombs_dynamic.c | 16 ++++++++++++++++ tests/test_wcstombs_static.c | 16 ++++++++++++++++ 28 files changed, 422 insertions(+), 36 deletions(-) create mode 100644 tests/test_confstr_static.c create mode 100644 tests/test_mbsrtowcs_dynamic.c create mode 100644 tests/test_mbsrtowcs_static.c create mode 100644 tests/test_mbstowcs_dynamic.c create mode 100644 tests/test_mbstowcs_static.c create mode 100644 tests/test_memcpy_overlap.c create mode 100644 tests/test_pread_dynamic.c create mode 100644 tests/test_pread_static.c create mode 100644 tests/test_readlinkat_dynamic.c create mode 100644 tests/test_readlinkat_static.c delete mode 100644 tests/test_select_dynamic.c delete mode 100644 tests/test_select_static.c create mode 100644 tests/test_snprintf_dynamic.c create mode 100644 tests/test_snprintf_static.c create mode 100644 tests/test_strcat_dynamic_write.c create mode 100644 tests/test_wcscat_dynamic_write.c create mode 100644 tests/test_wcscpy_dynamic_write.c create mode 100644 tests/test_wcsncat_dynamic_write.c create mode 100644 tests/test_wcsncpy_dynamic_write.c create mode 100644 tests/test_wcsrtombs_dynamic.c create mode 100644 tests/test_wcsrtombs_static.c create mode 100644 tests/test_wcstombs_dynamic.c create mode 100644 tests/test_wcstombs_static.c (limited to 'tests') diff --git a/tests/Makefile b/tests/Makefile index 9bedd16..1334efd 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -17,6 +17,7 @@ RUNTIME_TARGETS= \ test_bzero_static_write \ test_compile \ test_confstr_dynamic \ + test_confstr_static \ test_fgets_dynamic \ test_fgets_static \ test_fgetws_dynamic \ @@ -39,7 +40,9 @@ RUNTIME_TARGETS= \ test_getlogin_r_static \ test_memcpy_dynamic_read \ test_memcpy_dynamic_write \ + test_memcpy_overlap \ test_memcpy_static_read \ + test_memcpy_static_write \ test_memmove_dynamic_read \ test_memmove_dynamic_write \ test_memmove_static_read \ @@ -52,14 +55,22 @@ RUNTIME_TARGETS= \ test_memset_static_write \ test_mbsnrtowcs_dynamic \ test_mbsnrtowcs_static \ + test_mbsrtowcs_dynamic \ + test_mbsrtowcs_static \ + test_mbstowcs_dynamic \ + test_mbstowcs_static \ test_poll_dynamic \ test_poll_static \ test_ppoll_dynamic \ test_ppoll_static \ + test_pread_dynamic \ + test_pread_static \ test_read_dynamic \ test_read_static \ test_readlink_dynamic \ test_readlink_static \ + test_readlinkat_dynamic \ + test_readlinkat_static \ test_realpath_null \ test_realpath \ test_recv_dynamic \ @@ -70,12 +81,15 @@ RUNTIME_TARGETS= \ test_send_static \ test_sendto_dynamic \ test_sendto_static \ + test_snprintf_dynamic \ + test_snprintf_static \ test_sprintf \ test_sprintf_62 \ test_stpcpy_dynamic_write \ test_stpcpy_static_write \ test_stpncpy_dynamic_write \ test_stpncpy_static_write \ + test_strcat_dynamic_write \ test_strcat_static_write \ test_strcpy_dynamic_write \ test_strcpy_static_write \ @@ -96,6 +110,7 @@ RUNTIME_TARGETS= \ test_swab_dynamic_write \ test_swab_negative \ test_swab_static_read \ + test_swab_static_write \ test_ttyname_r_dynamic \ test_ttyname_r_static \ test_vsnprintf_dynamic \ @@ -104,15 +119,23 @@ RUNTIME_TARGETS= \ test_wcrtomb \ test_wcsnrtombs_dynamic \ test_wcsnrtombs_static \ + test_wcscat_dynamic_write \ test_wcscat_static_write \ + test_wcscpy_dynamic_write \ test_wcscpy_static_write \ + test_wcsncat_dynamic_write \ test_wcsncat_n_eq_buf \ test_wcsncat_n_gt_buf \ test_wcsncat_n_lt_buf \ test_wcsncat_n_one \ test_wcsncat_safe \ test_wcsncat_static_write \ + test_wcsncpy_dynamic_write \ test_wcsncpy_static_write \ + test_wcsrtombs_dynamic \ + test_wcsrtombs_static \ + test_wcstombs_dynamic \ + test_wcstombs_static \ test_wmemcpy_dynamic_read \ test_wmemcpy_dynamic_write \ test_wmemcpy_static_read \ diff --git a/tests/test_confstr_static.c b/tests/test_confstr_static.c new file mode 100644 index 0000000..f468532 --- /dev/null +++ b/tests/test_confstr_static.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + char buffer[4] = {0}; + + confstr(_CS_PATH, buffer, 4); + + CHK_FAIL_START + confstr(_CS_PATH, buffer, 8); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_mbsnrtowcs_dynamic.c b/tests/test_mbsnrtowcs_dynamic.c index 58575d3..b94ced5 100644 --- a/tests/test_mbsnrtowcs_dynamic.c +++ b/tests/test_mbsnrtowcs_dynamic.c @@ -15,9 +15,9 @@ int main(int argc, char** argv) { mbsnrtowcs(buffer, &srcp, 2, 2, &st); /* Unsafe: ask to write argc (10) wide chars into 4-element buffer. */ - CHK_FAIL_START srcp = src; memset(&st, 0, sizeof(st)); + CHK_FAIL_START mbsnrtowcs(buffer, &srcp, 10, argc, &st); CHK_FAIL_END diff --git a/tests/test_mbsnrtowcs_static.c b/tests/test_mbsnrtowcs_static.c index 755d453..40fe00a 100644 --- a/tests/test_mbsnrtowcs_static.c +++ b/tests/test_mbsnrtowcs_static.c @@ -15,9 +15,9 @@ int main(int argc, char** argv) { mbsnrtowcs(buffer, &srcp, 4, 2, &st); /* Unsafe: ask to write 16 wide chars into 4-element buffer */ - CHK_FAIL_START srcp = src; memset(&st, 0, sizeof(st)); + CHK_FAIL_START mbsnrtowcs(buffer, &srcp, 16, 16, &st); CHK_FAIL_END diff --git a/tests/test_mbsrtowcs_dynamic.c b/tests/test_mbsrtowcs_dynamic.c new file mode 100644 index 0000000..cbba0a3 --- /dev/null +++ b/tests/test_mbsrtowcs_dynamic.c @@ -0,0 +1,24 @@ +#include "common.h" + +#include +#include + +int main(int argc, char** argv) { + wchar_t buffer[4] = {0}; + const char *src = "ABCDEFGHIJ"; + const char *srcp = src; + mbstate_t st; + memset(&st, 0, sizeof(st)); + + srcp = src; + mbsrtowcs(buffer, &srcp, 2, &st); + + srcp = src; + memset(&st, 0, sizeof(st)); + CHK_FAIL_START + mbsrtowcs(buffer, &srcp, argc + 15, &st); + CHK_FAIL_END + + printf("%ls\n", buffer); + return ret; +} diff --git a/tests/test_mbsrtowcs_static.c b/tests/test_mbsrtowcs_static.c new file mode 100644 index 0000000..f90f29f --- /dev/null +++ b/tests/test_mbsrtowcs_static.c @@ -0,0 +1,24 @@ +#include "common.h" + +#include +#include + +int main(int argc, char** argv) { + wchar_t buffer[4] = {0}; + const char *src = "ABCDEFGHIJ"; + const char *srcp = src; + mbstate_t st; + memset(&st, 0, sizeof(st)); + + srcp = src; + mbsrtowcs(buffer, &srcp, 2, &st); + + srcp = src; + memset(&st, 0, sizeof(st)); + CHK_FAIL_START + mbsrtowcs(buffer, &srcp, 16, &st); + CHK_FAIL_END + + printf("%ls\n", buffer); + return ret; +} diff --git a/tests/test_mbstowcs_dynamic.c b/tests/test_mbstowcs_dynamic.c new file mode 100644 index 0000000..4295fbd --- /dev/null +++ b/tests/test_mbstowcs_dynamic.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + wchar_t buffer[4] = {0}; + + mbstowcs(buffer, "AB", 2); + + CHK_FAIL_START + mbstowcs(buffer, "ABCDEFGHIJ", argc + 15); + CHK_FAIL_END + + printf("%ls\n", buffer); + return ret; +} diff --git a/tests/test_mbstowcs_static.c b/tests/test_mbstowcs_static.c new file mode 100644 index 0000000..585c4f0 --- /dev/null +++ b/tests/test_mbstowcs_static.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + wchar_t buffer[4] = {0}; + + mbstowcs(buffer, "AB", 2); + + CHK_FAIL_START + mbstowcs(buffer, "ABCDEFGHIJ", 16); + CHK_FAIL_END + + printf("%ls\n", buffer); + return ret; +} diff --git a/tests/test_memcpy_overlap.c b/tests/test_memcpy_overlap.c new file mode 100644 index 0000000..f8c6639 --- /dev/null +++ b/tests/test_memcpy_overlap.c @@ -0,0 +1,27 @@ +#include "common.h" + +#include + +/* fortify-headers' memcpy traps when src/dst overlap (but not when src == dst). + * This test exercises that overlap-detection branch, which is unique to this + * implementation. The pointer offset is hidden behind a volatile so -Wrestrict + * cannot see the overlap at compile time. */ + +int main(int argc, char** argv) { + static char buffer[16] = "0123456789ABCDE"; + volatile int off = 2; /* hidden from the compiler so -Wrestrict won't see */ + char *p = buffer; + char *q = p + off; + + /* dst == src: must NOT trap */ + memcpy(p, p, 8); + puts(buffer); + + /* Overlapping src/dst (dst < src): must trap */ + CHK_FAIL_START + memcpy(p, q, 8); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_pread_dynamic.c b/tests/test_pread_dynamic.c new file mode 100644 index 0000000..a04c661 --- /dev/null +++ b/tests/test_pread_dynamic.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + char buffer[8] = {0}; + + pread(0, buffer, 6, 0); + + CHK_FAIL_START + pread(0, buffer, argc, 0); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_pread_static.c b/tests/test_pread_static.c new file mode 100644 index 0000000..919fff7 --- /dev/null +++ b/tests/test_pread_static.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + char buffer[12] = {0}; + + pread(0, buffer, 10, 0); + + CHK_FAIL_START + pread(0, buffer, 14, 0); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_readlinkat_dynamic.c b/tests/test_readlinkat_dynamic.c new file mode 100644 index 0000000..6976b74 --- /dev/null +++ b/tests/test_readlinkat_dynamic.c @@ -0,0 +1,17 @@ +#include "common.h" + +#include +#include + +int main(int argc, char** argv) { + char buffer[8] = {0}; + + readlinkat(AT_FDCWD, "", buffer, 6); + + CHK_FAIL_START + readlinkat(AT_FDCWD, "", buffer, argc); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_readlinkat_static.c b/tests/test_readlinkat_static.c new file mode 100644 index 0000000..3331b1e --- /dev/null +++ b/tests/test_readlinkat_static.c @@ -0,0 +1,17 @@ +#include "common.h" + +#include +#include + +int main(int argc, char** argv) { + char buffer[12] = {0}; + + readlinkat(AT_FDCWD, "", buffer, 10); + + CHK_FAIL_START + readlinkat(AT_FDCWD, "", buffer, 14); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_select_dynamic.c b/tests/test_select_dynamic.c deleted file mode 100644 index e67baf3..0000000 --- a/tests/test_select_dynamic.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "common.h" - -#include - -int main(int argc, char** argv) { -#if !defined(__clang__) - fd_set rfds; - - CHK_FAIL_START - select(FD_SETSIZE + argc, &rfds, NULL, NULL, NULL); - CHK_FAIL_END - - puts((const char*)&rfds); -#endif - return ret; -} diff --git a/tests/test_select_static.c b/tests/test_select_static.c deleted file mode 100644 index c2abf7f..0000000 --- a/tests/test_select_static.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "common.h" - -#include - -int main(int argc, char** argv) { -#if !defined(__clang__) - fd_set rfds; - - CHK_FAIL_START - select(1337, &rfds, NULL, NULL, NULL); - CHK_FAIL_END - - puts((const char*)&rfds); -#endif - return ret; -} diff --git a/tests/test_snprintf_dynamic.c b/tests/test_snprintf_dynamic.c new file mode 100644 index 0000000..e5f8fcc --- /dev/null +++ b/tests/test_snprintf_dynamic.c @@ -0,0 +1,18 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { +#if !defined(__clang__) + char buffer[8] = {0}; + snprintf(buffer, sizeof(buffer), "%s", "1234567"); + puts(buffer); + + CHK_FAIL_START + snprintf(buffer, sizeof(buffer) + argc + 3, "%s", "1234567890"); + CHK_FAIL_END + + puts(buffer); +#endif + return ret; +} diff --git a/tests/test_snprintf_static.c b/tests/test_snprintf_static.c new file mode 100644 index 0000000..d3df447 --- /dev/null +++ b/tests/test_snprintf_static.c @@ -0,0 +1,18 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { +#if !defined(__clang__) + char buffer[8] = {0}; + snprintf(buffer, sizeof(buffer), "%s", "1234567"); + puts(buffer); + + CHK_FAIL_START + snprintf(buffer, sizeof(buffer) + 4, "%s", "1234567890"); + CHK_FAIL_END + + puts(buffer); +#endif + return ret; +} diff --git a/tests/test_strcat_dynamic_write.c b/tests/test_strcat_dynamic_write.c new file mode 100644 index 0000000..dde9e44 --- /dev/null +++ b/tests/test_strcat_dynamic_write.c @@ -0,0 +1,15 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + char buffer[8] = {0}; + strcat(buffer, "12345"); + + CHK_FAIL_START + strcat(buffer, argv[1]); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_wcscat_dynamic_write.c b/tests/test_wcscat_dynamic_write.c new file mode 100644 index 0000000..064f018 --- /dev/null +++ b/tests/test_wcscat_dynamic_write.c @@ -0,0 +1,21 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + wchar_t buffer[8] = {0}; + wchar_t src[20]; + int i; + wcscat(buffer, L"α"); + + for (i = 0; i < argc; i++) + src[i] = L'A'; + src[i] = L'\0'; + + CHK_FAIL_START + wcscat(buffer, src); + CHK_FAIL_END + + printf("%ls\n", buffer); + return ret; +} diff --git a/tests/test_wcscpy_dynamic_write.c b/tests/test_wcscpy_dynamic_write.c new file mode 100644 index 0000000..5055e9c --- /dev/null +++ b/tests/test_wcscpy_dynamic_write.c @@ -0,0 +1,22 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + wchar_t buffer[8] = {0}; + wchar_t src[20]; + int i; + wcscpy(buffer, L"α"); + printf("%ls\n", buffer); + + for (i = 0; i < argc; i++) + src[i] = L'A'; + src[i] = L'\0'; + + CHK_FAIL_START + wcscpy(buffer, src); + CHK_FAIL_END + + printf("%ls\n", buffer); + return ret; +} diff --git a/tests/test_wcsncat_dynamic_write.c b/tests/test_wcsncat_dynamic_write.c new file mode 100644 index 0000000..9f87172 --- /dev/null +++ b/tests/test_wcsncat_dynamic_write.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + wchar_t buffer[8] = {0}; + wcsncat(buffer, L"αβγδεζηθικλμνξοπρστυφχψω", 2); + printf("%ls\n", buffer); + + CHK_FAIL_START + wcsncat(buffer, L"αβγδεζηθικλμνξοπρστυφχψω", argc + 1336); + CHK_FAIL_END + + printf("%ls\n", buffer); + return ret; +} diff --git a/tests/test_wcsncpy_dynamic_write.c b/tests/test_wcsncpy_dynamic_write.c new file mode 100644 index 0000000..3078c0e --- /dev/null +++ b/tests/test_wcsncpy_dynamic_write.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + wchar_t buffer[8] = {0}; + wcsncpy(buffer, L"αβγδεζηθικλμνξοπρστυφχψω", 1); + printf("%ls\n", buffer); + + CHK_FAIL_START + wcsncpy(buffer, L"αβγδεζηθικλμνξοπρστυφχψω", argc + 1336); + CHK_FAIL_END + + printf("%ls\n", buffer); + return ret; +} diff --git a/tests/test_wcsnrtombs_dynamic.c b/tests/test_wcsnrtombs_dynamic.c index 28b03bf..1637e71 100644 --- a/tests/test_wcsnrtombs_dynamic.c +++ b/tests/test_wcsnrtombs_dynamic.c @@ -15,9 +15,9 @@ int main(int argc, char** argv) { wcsnrtombs(buffer, &srcp, 4, 4, &st); /* Unsafe: ask to write argc (10) bytes into 8-byte buffer. */ - CHK_FAIL_START srcp = src; memset(&st, 0, sizeof(st)); + CHK_FAIL_START wcsnrtombs(buffer, &srcp, 4, argc, &st); CHK_FAIL_END diff --git a/tests/test_wcsnrtombs_static.c b/tests/test_wcsnrtombs_static.c index 7f2883f..da529f1 100644 --- a/tests/test_wcsnrtombs_static.c +++ b/tests/test_wcsnrtombs_static.c @@ -15,9 +15,9 @@ int main(int argc, char** argv) { wcsnrtombs(buffer, &srcp, 2, 2, &st); /* Unsafe: ask to write 16 bytes into 4-byte buffer */ - CHK_FAIL_START srcp = src; memset(&st, 0, sizeof(st)); + CHK_FAIL_START wcsnrtombs(buffer, &srcp, 10, 16, &st); CHK_FAIL_END diff --git a/tests/test_wcsrtombs_dynamic.c b/tests/test_wcsrtombs_dynamic.c new file mode 100644 index 0000000..674a75f --- /dev/null +++ b/tests/test_wcsrtombs_dynamic.c @@ -0,0 +1,24 @@ +#include "common.h" + +#include +#include + +int main(int argc, char** argv) { + char buffer[4] = {0}; + const wchar_t src[] = L"ABCDEFGHIJ"; + const wchar_t *srcp = src; + mbstate_t st; + memset(&st, 0, sizeof(st)); + + srcp = src; + wcsrtombs(buffer, &srcp, 2, &st); + + srcp = src; + memset(&st, 0, sizeof(st)); + CHK_FAIL_START + wcsrtombs(buffer, &srcp, argc + 15, &st); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_wcsrtombs_static.c b/tests/test_wcsrtombs_static.c new file mode 100644 index 0000000..ffb4919 --- /dev/null +++ b/tests/test_wcsrtombs_static.c @@ -0,0 +1,24 @@ +#include "common.h" + +#include +#include + +int main(int argc, char** argv) { + char buffer[4] = {0}; + const wchar_t src[] = L"ABCDEFGHIJ"; + const wchar_t *srcp = src; + mbstate_t st; + memset(&st, 0, sizeof(st)); + + srcp = src; + wcsrtombs(buffer, &srcp, 2, &st); + + srcp = src; + memset(&st, 0, sizeof(st)); + CHK_FAIL_START + wcsrtombs(buffer, &srcp, 16, &st); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_wcstombs_dynamic.c b/tests/test_wcstombs_dynamic.c new file mode 100644 index 0000000..6f3962d --- /dev/null +++ b/tests/test_wcstombs_dynamic.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + char buffer[4] = {0}; + + wcstombs(buffer, L"AB", 2); + + CHK_FAIL_START + wcstombs(buffer, L"ABCDEFGHIJ", argc + 15); + CHK_FAIL_END + + puts(buffer); + return ret; +} diff --git a/tests/test_wcstombs_static.c b/tests/test_wcstombs_static.c new file mode 100644 index 0000000..5939793 --- /dev/null +++ b/tests/test_wcstombs_static.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include + +int main(int argc, char** argv) { + char buffer[4] = {0}; + + wcstombs(buffer, L"AB", 2); + + CHK_FAIL_START + wcstombs(buffer, L"ABCDEFGHIJ", 16); + CHK_FAIL_END + + puts(buffer); + return ret; +} -- cgit v1.3