diff options
Diffstat (limited to 'tests')
47 files changed, 851 insertions, 40 deletions
diff --git a/tests/Makefile b/tests/Makefile index d19e3d8..1334efd 100644 --- a/tests/Makefile +++ b/tests/Makefile | |||
| @@ -17,6 +17,7 @@ RUNTIME_TARGETS= \ | |||
| 17 | test_bzero_static_write \ | 17 | test_bzero_static_write \ |
| 18 | test_compile \ | 18 | test_compile \ |
| 19 | test_confstr_dynamic \ | 19 | test_confstr_dynamic \ |
| 20 | test_confstr_static \ | ||
| 20 | test_fgets_dynamic \ | 21 | test_fgets_dynamic \ |
| 21 | test_fgets_static \ | 22 | test_fgets_static \ |
| 22 | test_fgetws_dynamic \ | 23 | test_fgetws_dynamic \ |
| @@ -39,7 +40,9 @@ RUNTIME_TARGETS= \ | |||
| 39 | test_getlogin_r_static \ | 40 | test_getlogin_r_static \ |
| 40 | test_memcpy_dynamic_read \ | 41 | test_memcpy_dynamic_read \ |
| 41 | test_memcpy_dynamic_write \ | 42 | test_memcpy_dynamic_write \ |
| 43 | test_memcpy_overlap \ | ||
| 42 | test_memcpy_static_read \ | 44 | test_memcpy_static_read \ |
| 45 | test_memcpy_static_write \ | ||
| 43 | test_memmove_dynamic_read \ | 46 | test_memmove_dynamic_read \ |
| 44 | test_memmove_dynamic_write \ | 47 | test_memmove_dynamic_write \ |
| 45 | test_memmove_static_read \ | 48 | test_memmove_static_read \ |
| @@ -50,14 +53,24 @@ RUNTIME_TARGETS= \ | |||
| 50 | test_mempcpy_static_write \ | 53 | test_mempcpy_static_write \ |
| 51 | test_memset_dynamic_write \ | 54 | test_memset_dynamic_write \ |
| 52 | test_memset_static_write \ | 55 | test_memset_static_write \ |
| 56 | test_mbsnrtowcs_dynamic \ | ||
| 57 | test_mbsnrtowcs_static \ | ||
| 58 | test_mbsrtowcs_dynamic \ | ||
| 59 | test_mbsrtowcs_static \ | ||
| 60 | test_mbstowcs_dynamic \ | ||
| 61 | test_mbstowcs_static \ | ||
| 53 | test_poll_dynamic \ | 62 | test_poll_dynamic \ |
| 54 | test_poll_static \ | 63 | test_poll_static \ |
| 55 | test_ppoll_dynamic \ | 64 | test_ppoll_dynamic \ |
| 56 | test_ppoll_static \ | 65 | test_ppoll_static \ |
| 66 | test_pread_dynamic \ | ||
| 67 | test_pread_static \ | ||
| 57 | test_read_dynamic \ | 68 | test_read_dynamic \ |
| 58 | test_read_static \ | 69 | test_read_static \ |
| 59 | test_readlink_dynamic \ | 70 | test_readlink_dynamic \ |
| 60 | test_readlink_static \ | 71 | test_readlink_static \ |
| 72 | test_readlinkat_dynamic \ | ||
| 73 | test_readlinkat_static \ | ||
| 61 | test_realpath_null \ | 74 | test_realpath_null \ |
| 62 | test_realpath \ | 75 | test_realpath \ |
| 63 | test_recv_dynamic \ | 76 | test_recv_dynamic \ |
| @@ -68,12 +81,15 @@ RUNTIME_TARGETS= \ | |||
| 68 | test_send_static \ | 81 | test_send_static \ |
| 69 | test_sendto_dynamic \ | 82 | test_sendto_dynamic \ |
| 70 | test_sendto_static \ | 83 | test_sendto_static \ |
| 84 | test_snprintf_dynamic \ | ||
| 85 | test_snprintf_static \ | ||
| 71 | test_sprintf \ | 86 | test_sprintf \ |
| 72 | test_sprintf_62 \ | 87 | test_sprintf_62 \ |
| 73 | test_stpcpy_dynamic_write \ | 88 | test_stpcpy_dynamic_write \ |
| 74 | test_stpcpy_static_write \ | 89 | test_stpcpy_static_write \ |
| 75 | test_stpncpy_dynamic_write \ | 90 | test_stpncpy_dynamic_write \ |
| 76 | test_stpncpy_static_write \ | 91 | test_stpncpy_static_write \ |
| 92 | test_strcat_dynamic_write \ | ||
| 77 | test_strcat_static_write \ | 93 | test_strcat_static_write \ |
| 78 | test_strcpy_dynamic_write \ | 94 | test_strcpy_dynamic_write \ |
| 79 | test_strcpy_static_write \ | 95 | test_strcpy_static_write \ |
| @@ -82,24 +98,51 @@ RUNTIME_TARGETS= \ | |||
| 82 | test_strlcpy_dynamic_write \ | 98 | test_strlcpy_dynamic_write \ |
| 83 | test_strlcpy_static_write \ | 99 | test_strlcpy_static_write \ |
| 84 | test_strncat_dynamic_write \ | 100 | test_strncat_dynamic_write \ |
| 101 | test_strncat_n_eq_buf \ | ||
| 102 | test_strncat_n_gt_buf \ | ||
| 103 | test_strncat_n_lt_buf \ | ||
| 104 | test_strncat_n_one \ | ||
| 105 | test_strncat_safe \ | ||
| 85 | test_strncat_static_write \ | 106 | test_strncat_static_write \ |
| 86 | test_strncpy_dynamic_write \ | 107 | test_strncpy_dynamic_write \ |
| 87 | test_strncpy_static_write \ | 108 | test_strncpy_static_write \ |
| 88 | test_swab_dynamic_read \ | 109 | test_swab_dynamic_read \ |
| 89 | test_swab_dynamic_write \ | 110 | test_swab_dynamic_write \ |
| 111 | test_swab_negative \ | ||
| 90 | test_swab_static_read \ | 112 | test_swab_static_read \ |
| 113 | test_swab_static_write \ | ||
| 91 | test_ttyname_r_dynamic \ | 114 | test_ttyname_r_dynamic \ |
| 92 | test_ttyname_r_static \ | 115 | test_ttyname_r_static \ |
| 93 | test_vsnprintf_dynamic \ | 116 | test_vsnprintf_dynamic \ |
| 94 | test_vsnprintf_static \ | 117 | test_vsnprintf_static \ |
| 95 | test_vsprintf \ | 118 | test_vsprintf \ |
| 119 | test_wcrtomb \ | ||
| 120 | test_wcsnrtombs_dynamic \ | ||
| 121 | test_wcsnrtombs_static \ | ||
| 122 | test_wcscat_dynamic_write \ | ||
| 96 | test_wcscat_static_write \ | 123 | test_wcscat_static_write \ |
| 124 | test_wcscpy_dynamic_write \ | ||
| 97 | test_wcscpy_static_write \ | 125 | test_wcscpy_static_write \ |
| 126 | test_wcsncat_dynamic_write \ | ||
| 127 | test_wcsncat_n_eq_buf \ | ||
| 128 | test_wcsncat_n_gt_buf \ | ||
| 129 | test_wcsncat_n_lt_buf \ | ||
| 130 | test_wcsncat_n_one \ | ||
| 131 | test_wcsncat_safe \ | ||
| 98 | test_wcsncat_static_write \ | 132 | test_wcsncat_static_write \ |
| 133 | test_wcsncpy_dynamic_write \ | ||
| 99 | test_wcsncpy_static_write \ | 134 | test_wcsncpy_static_write \ |
| 135 | test_wcsrtombs_dynamic \ | ||
| 136 | test_wcsrtombs_static \ | ||
| 137 | test_wcstombs_dynamic \ | ||
| 138 | test_wcstombs_static \ | ||
| 139 | test_wmemcpy_dynamic_read \ | ||
| 100 | test_wmemcpy_dynamic_write \ | 140 | test_wmemcpy_dynamic_write \ |
| 141 | test_wmemcpy_static_read \ | ||
| 101 | test_wmemcpy_static_write \ | 142 | test_wmemcpy_static_write \ |
| 143 | test_wmemmove_dynamic_read \ | ||
| 102 | test_wmemmove_dynamic_write \ | 144 | test_wmemmove_dynamic_write \ |
| 145 | test_wmemmove_static_read \ | ||
| 103 | test_wmemmove_static_write \ | 146 | test_wmemmove_static_write \ |
| 104 | test_wmemset_dynamic \ | 147 | test_wmemset_dynamic \ |
| 105 | test_wmemset_static \ | 148 | test_wmemset_static \ |
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <unistd.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[4] = {0}; | ||
| 7 | |||
| 8 | confstr(_CS_PATH, buffer, 4); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | confstr(_CS_PATH, buffer, 8); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | puts(buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
diff --git a/tests/test_mbsnrtowcs_dynamic.c b/tests/test_mbsnrtowcs_dynamic.c new file mode 100644 index 0000000..b94ced5 --- /dev/null +++ b/tests/test_mbsnrtowcs_dynamic.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | wchar_t buffer[4] = {0}; | ||
| 8 | const char *src = "ABCDEFGHIJ"; | ||
| 9 | const char *srcp = src; | ||
| 10 | mbstate_t st; | ||
| 11 | memset(&st, 0, sizeof(st)); | ||
| 12 | |||
| 13 | /* Safe: convert up to 2 source bytes into at most 2 wide chars */ | ||
| 14 | srcp = src; | ||
| 15 | mbsnrtowcs(buffer, &srcp, 2, 2, &st); | ||
| 16 | |||
| 17 | /* Unsafe: ask to write argc (10) wide chars into 4-element buffer. */ | ||
| 18 | srcp = src; | ||
| 19 | memset(&st, 0, sizeof(st)); | ||
| 20 | CHK_FAIL_START | ||
| 21 | mbsnrtowcs(buffer, &srcp, 10, argc, &st); | ||
| 22 | CHK_FAIL_END | ||
| 23 | |||
| 24 | printf("%ls\n", buffer); | ||
| 25 | return ret; | ||
| 26 | } | ||
diff --git a/tests/test_mbsnrtowcs_static.c b/tests/test_mbsnrtowcs_static.c new file mode 100644 index 0000000..40fe00a --- /dev/null +++ b/tests/test_mbsnrtowcs_static.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | wchar_t buffer[4] = {0}; | ||
| 8 | const char *src = "ABCDEFGHIJKLMNOP"; | ||
| 9 | const char *srcp = src; | ||
| 10 | mbstate_t st; | ||
| 11 | memset(&st, 0, sizeof(st)); | ||
| 12 | |||
| 13 | /* Safe: convert up to 4 source bytes into at most 2 wide chars */ | ||
| 14 | srcp = src; | ||
| 15 | mbsnrtowcs(buffer, &srcp, 4, 2, &st); | ||
| 16 | |||
| 17 | /* Unsafe: ask to write 16 wide chars into 4-element buffer */ | ||
| 18 | srcp = src; | ||
| 19 | memset(&st, 0, sizeof(st)); | ||
| 20 | CHK_FAIL_START | ||
| 21 | mbsnrtowcs(buffer, &srcp, 16, 16, &st); | ||
| 22 | CHK_FAIL_END | ||
| 23 | |||
| 24 | printf("%ls\n", buffer); | ||
| 25 | return ret; | ||
| 26 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | wchar_t buffer[4] = {0}; | ||
| 8 | const char *src = "ABCDEFGHIJ"; | ||
| 9 | const char *srcp = src; | ||
| 10 | mbstate_t st; | ||
| 11 | memset(&st, 0, sizeof(st)); | ||
| 12 | |||
| 13 | srcp = src; | ||
| 14 | mbsrtowcs(buffer, &srcp, 2, &st); | ||
| 15 | |||
| 16 | srcp = src; | ||
| 17 | memset(&st, 0, sizeof(st)); | ||
| 18 | CHK_FAIL_START | ||
| 19 | mbsrtowcs(buffer, &srcp, argc + 15, &st); | ||
| 20 | CHK_FAIL_END | ||
| 21 | |||
| 22 | printf("%ls\n", buffer); | ||
| 23 | return ret; | ||
| 24 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | wchar_t buffer[4] = {0}; | ||
| 8 | const char *src = "ABCDEFGHIJ"; | ||
| 9 | const char *srcp = src; | ||
| 10 | mbstate_t st; | ||
| 11 | memset(&st, 0, sizeof(st)); | ||
| 12 | |||
| 13 | srcp = src; | ||
| 14 | mbsrtowcs(buffer, &srcp, 2, &st); | ||
| 15 | |||
| 16 | srcp = src; | ||
| 17 | memset(&st, 0, sizeof(st)); | ||
| 18 | CHK_FAIL_START | ||
| 19 | mbsrtowcs(buffer, &srcp, 16, &st); | ||
| 20 | CHK_FAIL_END | ||
| 21 | |||
| 22 | printf("%ls\n", buffer); | ||
| 23 | return ret; | ||
| 24 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[4] = {0}; | ||
| 7 | |||
| 8 | mbstowcs(buffer, "AB", 2); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | mbstowcs(buffer, "ABCDEFGHIJ", argc + 15); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | printf("%ls\n", buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[4] = {0}; | ||
| 7 | |||
| 8 | mbstowcs(buffer, "AB", 2); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | mbstowcs(buffer, "ABCDEFGHIJ", 16); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | printf("%ls\n", buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | |||
| 5 | /* fortify-headers' memcpy traps when src/dst overlap (but not when src == dst). | ||
| 6 | * This test exercises that overlap-detection branch, which is unique to this | ||
| 7 | * implementation. The pointer offset is hidden behind a volatile so -Wrestrict | ||
| 8 | * cannot see the overlap at compile time. */ | ||
| 9 | |||
| 10 | int main(int argc, char** argv) { | ||
| 11 | static char buffer[16] = "0123456789ABCDE"; | ||
| 12 | volatile int off = 2; /* hidden from the compiler so -Wrestrict won't see */ | ||
| 13 | char *p = buffer; | ||
| 14 | char *q = p + off; | ||
| 15 | |||
| 16 | /* dst == src: must NOT trap */ | ||
| 17 | memcpy(p, p, 8); | ||
| 18 | puts(buffer); | ||
| 19 | |||
| 20 | /* Overlapping src/dst (dst < src): must trap */ | ||
| 21 | CHK_FAIL_START | ||
| 22 | memcpy(p, q, 8); | ||
| 23 | CHK_FAIL_END | ||
| 24 | |||
| 25 | puts(buffer); | ||
| 26 | return ret; | ||
| 27 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <unistd.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[8] = {0}; | ||
| 7 | |||
| 8 | pread(0, buffer, 6, 0); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | pread(0, buffer, argc, 0); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | puts(buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <unistd.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[12] = {0}; | ||
| 7 | |||
| 8 | pread(0, buffer, 10, 0); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | pread(0, buffer, 14, 0); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | puts(buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <fcntl.h> | ||
| 4 | #include <unistd.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | char buffer[8] = {0}; | ||
| 8 | |||
| 9 | readlinkat(AT_FDCWD, "", buffer, 6); | ||
| 10 | |||
| 11 | CHK_FAIL_START | ||
| 12 | readlinkat(AT_FDCWD, "", buffer, argc); | ||
| 13 | CHK_FAIL_END | ||
| 14 | |||
| 15 | puts(buffer); | ||
| 16 | return ret; | ||
| 17 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <fcntl.h> | ||
| 4 | #include <unistd.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | char buffer[12] = {0}; | ||
| 8 | |||
| 9 | readlinkat(AT_FDCWD, "", buffer, 10); | ||
| 10 | |||
| 11 | CHK_FAIL_START | ||
| 12 | readlinkat(AT_FDCWD, "", buffer, 14); | ||
| 13 | CHK_FAIL_END | ||
| 14 | |||
| 15 | puts(buffer); | ||
| 16 | return ret; | ||
| 17 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <sys/select.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | #if !defined(__clang__) | ||
| 7 | fd_set rfds; | ||
| 8 | |||
| 9 | CHK_FAIL_START | ||
| 10 | select(FD_SETSIZE + argc, &rfds, NULL, NULL, NULL); | ||
| 11 | CHK_FAIL_END | ||
| 12 | |||
| 13 | puts((const char*)&rfds); | ||
| 14 | #endif | ||
| 15 | return ret; | ||
| 16 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <sys/select.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | #if !defined(__clang__) | ||
| 7 | fd_set rfds; | ||
| 8 | |||
| 9 | CHK_FAIL_START | ||
| 10 | select(1337, &rfds, NULL, NULL, NULL); | ||
| 11 | CHK_FAIL_END | ||
| 12 | |||
| 13 | puts((const char*)&rfds); | ||
| 14 | #endif | ||
| 15 | return ret; | ||
| 16 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <stdio.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | #if !defined(__clang__) | ||
| 7 | char buffer[8] = {0}; | ||
| 8 | snprintf(buffer, sizeof(buffer), "%s", "1234567"); | ||
| 9 | puts(buffer); | ||
| 10 | |||
| 11 | CHK_FAIL_START | ||
| 12 | snprintf(buffer, sizeof(buffer) + argc + 3, "%s", "1234567890"); | ||
| 13 | CHK_FAIL_END | ||
| 14 | |||
| 15 | puts(buffer); | ||
| 16 | #endif | ||
| 17 | return ret; | ||
| 18 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <stdio.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | #if !defined(__clang__) | ||
| 7 | char buffer[8] = {0}; | ||
| 8 | snprintf(buffer, sizeof(buffer), "%s", "1234567"); | ||
| 9 | puts(buffer); | ||
| 10 | |||
| 11 | CHK_FAIL_START | ||
| 12 | snprintf(buffer, sizeof(buffer) + 4, "%s", "1234567890"); | ||
| 13 | CHK_FAIL_END | ||
| 14 | |||
| 15 | puts(buffer); | ||
| 16 | #endif | ||
| 17 | return ret; | ||
| 18 | } | ||
diff --git a/tests/test_stpncpy_static_write.c b/tests/test_stpncpy_static_write.c index 4bf9092..d4202ba 100644 --- a/tests/test_stpncpy_static_write.c +++ b/tests/test_stpncpy_static_write.c | |||
| @@ -4,7 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | int main(int argc, char** argv) { | 5 | int main(int argc, char** argv) { |
| 6 | char buffer[8] = {0}; | 6 | char buffer[8] = {0}; |
| 7 | stpncpy(buffer, "1234567", 5); | 7 | stpncpy(buffer, "1234567890", 5); |
| 8 | stpncpy(buffer, "1234567890", 8); | ||
| 8 | puts(buffer); | 9 | puts(buffer); |
| 9 | 10 | ||
| 10 | CHK_FAIL_START | 11 | CHK_FAIL_START |
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[8] = {0}; | ||
| 7 | strcat(buffer, "12345"); | ||
| 8 | |||
| 9 | CHK_FAIL_START | ||
| 10 | strcat(buffer, argv[1]); | ||
| 11 | CHK_FAIL_END | ||
| 12 | |||
| 13 | puts(buffer); | ||
| 14 | return ret; | ||
| 15 | } | ||
diff --git a/tests/test_strncat_dynamic_write.c b/tests/test_strncat_dynamic_write.c index d5c5a94..c538339 100644 --- a/tests/test_strncat_dynamic_write.c +++ b/tests/test_strncat_dynamic_write.c | |||
| @@ -7,11 +7,9 @@ int main(int argc, char** argv) { | |||
| 7 | strncat(buffer, "1234567", 5); | 7 | strncat(buffer, "1234567", 5); |
| 8 | puts(buffer); | 8 | puts(buffer); |
| 9 | 9 | ||
| 10 | #if 0 | ||
| 11 | CHK_FAIL_START | 10 | CHK_FAIL_START |
| 12 | strncat(buffer, argv[1], argc); | 11 | strncat(buffer, argv[1], argc); |
| 13 | CHK_FAIL_END | 12 | CHK_FAIL_END |
| 14 | #endif | ||
| 15 | 13 | ||
| 16 | puts(buffer); | 14 | puts(buffer); |
| 17 | return ret; | 15 | return ret; |
diff --git a/tests/test_strncat_n_eq_buf.c b/tests/test_strncat_n_eq_buf.c new file mode 100644 index 0000000..bbc39d2 --- /dev/null +++ b/tests/test_strncat_n_eq_buf.c | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[8] = {0}; | ||
| 7 | strncat(buffer, "12345", 5); | ||
| 8 | puts(buffer); | ||
| 9 | |||
| 10 | /* n == buffer size but overflow due to existing content. | ||
| 11 | * buffer has 5 chars, src "ABC" (len 3): 5+3+1 = 9 > 8 → overflow. */ | ||
| 12 | CHK_FAIL_START | ||
| 13 | strncat(buffer, "ABC", 8); | ||
| 14 | CHK_FAIL_END | ||
| 15 | |||
| 16 | puts(buffer); | ||
| 17 | return ret; | ||
| 18 | } | ||
diff --git a/tests/test_strncat_n_gt_buf.c b/tests/test_strncat_n_gt_buf.c new file mode 100644 index 0000000..cca226b --- /dev/null +++ b/tests/test_strncat_n_gt_buf.c | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[8] = {0}; | ||
| 7 | strncat(buffer, "12345", 5); | ||
| 8 | puts(buffer); | ||
| 9 | |||
| 10 | /* n > buffer size and overflow: n=10, buffer has 5 chars. */ | ||
| 11 | CHK_FAIL_START | ||
| 12 | strncat(buffer, "1234567890", 10); | ||
| 13 | CHK_FAIL_END | ||
| 14 | |||
| 15 | puts(buffer); | ||
| 16 | return ret; | ||
| 17 | } | ||
diff --git a/tests/test_strncat_n_lt_buf.c b/tests/test_strncat_n_lt_buf.c new file mode 100644 index 0000000..35a0ba1 --- /dev/null +++ b/tests/test_strncat_n_lt_buf.c | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[8] = {0}; | ||
| 7 | strncat(buffer, "12345", 5); | ||
| 8 | puts(buffer); | ||
| 9 | |||
| 10 | /* n < buffer size but overflow due to existing content. | ||
| 11 | * buffer has 5 chars, src "ABCD" (len 4), min(4,3)=3: 5+3+1 = 9 > 8. */ | ||
| 12 | CHK_FAIL_START | ||
| 13 | strncat(buffer, "ABCD", 3); | ||
| 14 | CHK_FAIL_END | ||
| 15 | |||
| 16 | puts(buffer); | ||
| 17 | return ret; | ||
| 18 | } | ||
diff --git a/tests/test_strncat_n_one.c b/tests/test_strncat_n_one.c new file mode 100644 index 0000000..fce46bd --- /dev/null +++ b/tests/test_strncat_n_one.c | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[8] = {0}; | ||
| 7 | strncat(buffer, "1234567", 7); | ||
| 8 | puts(buffer); | ||
| 9 | |||
| 10 | /* n=1, buffer has 7 chars ("1234567"). | ||
| 11 | * 7+1+1 = 9 > 8 → overflow. Even n=1 can overflow a nearly-full buffer. */ | ||
| 12 | CHK_FAIL_START | ||
| 13 | strncat(buffer, "X", 1); | ||
| 14 | CHK_FAIL_END | ||
| 15 | |||
| 16 | puts(buffer); | ||
| 17 | return ret; | ||
| 18 | } | ||
diff --git a/tests/test_strncat_safe.c b/tests/test_strncat_safe.c new file mode 100644 index 0000000..ff8cadd --- /dev/null +++ b/tests/test_strncat_safe.c | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[8] = {0}; | ||
| 7 | |||
| 8 | /* Safe: empty buffer, append 7 chars with n=7 → "1234567\0" = exactly 8 bytes */ | ||
| 9 | strncat(buffer, "1234567", 7); | ||
| 10 | puts(buffer); | ||
| 11 | |||
| 12 | /* Safe: reset and append with n larger than source. | ||
| 13 | * src is "AB" (len 2), n=100 → only 2 chars copied + NUL = 3 bytes */ | ||
| 14 | buffer[0] = '\0'; | ||
| 15 | strncat(buffer, "AB", 100); | ||
| 16 | puts(buffer); | ||
| 17 | |||
| 18 | /* Safe: partially filled, append fits exactly. | ||
| 19 | * buffer = "ABCD" (4 chars), append "EFG" with n=3 → 4+3+1 = 8 = exact fit */ | ||
| 20 | buffer[0] = '\0'; | ||
| 21 | strncat(buffer, "ABCD", 4); | ||
| 22 | strncat(buffer, "EFG", 3); | ||
| 23 | puts(buffer); | ||
| 24 | |||
| 25 | /* Safe: n limits copy to fit. | ||
| 26 | * buffer = "ABCDE" (5 chars), src = "FGHIJKLM" (8 chars), n=2 → 5+2+1 = 8 */ | ||
| 27 | buffer[0] = '\0'; | ||
| 28 | strncat(buffer, "ABCDE", 5); | ||
| 29 | strncat(buffer, "FGHIJKLM", 2); | ||
| 30 | puts(buffer); | ||
| 31 | |||
| 32 | /* All safe operations passed without trapping */ | ||
| 33 | return 0; | ||
| 34 | } | ||
diff --git a/tests/test_strncat_static_write.c b/tests/test_strncat_static_write.c index 7fe89ff..53d1532 100644 --- a/tests/test_strncat_static_write.c +++ b/tests/test_strncat_static_write.c | |||
| @@ -4,15 +4,15 @@ | |||
| 4 | 4 | ||
| 5 | int main(int argc, char** argv) { | 5 | int main(int argc, char** argv) { |
| 6 | char buffer[8] = {0}; | 6 | char buffer[8] = {0}; |
| 7 | char src[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; | 7 | strncat(buffer, "12345", 5); |
| 8 | strncat(buffer, src, 5); | ||
| 9 | puts(buffer); | 8 | puts(buffer); |
| 10 | 9 | ||
| 11 | #if 0 | 10 | /* n=4 is less than buffer size (8), but buffer already has 5 chars, |
| 11 | * so appending 4 more + NUL = 10 bytes total, overflowing the buffer. | ||
| 12 | */ | ||
| 12 | CHK_FAIL_START | 13 | CHK_FAIL_START |
| 13 | strncat(buffer, src, 10); | 14 | strncat(buffer, "ABCD", 4); |
| 14 | CHK_FAIL_END | 15 | CHK_FAIL_END |
| 15 | #endif | ||
| 16 | 16 | ||
| 17 | puts(buffer); | 17 | puts(buffer); |
| 18 | return ret; | 18 | return ret; |
diff --git a/tests/test_swab_negative.c b/tests/test_swab_negative.c new file mode 100644 index 0000000..f9c182b --- /dev/null +++ b/tests/test_swab_negative.c | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <unistd.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char src[8] = "ABCDEFG"; | ||
| 7 | char dst[8] = {0}; | ||
| 8 | |||
| 9 | /* Positive case: normal swab works */ | ||
| 10 | swab(src, dst, 6); | ||
| 11 | puts(dst); | ||
| 12 | |||
| 13 | /* Negative n: POSIX says swab does nothing, must NOT trap */ | ||
| 14 | swab(src, dst, -1); | ||
| 15 | swab(src, dst, -100); | ||
| 16 | |||
| 17 | puts(dst); | ||
| 18 | return ret; | ||
| 19 | } | ||
diff --git a/tests/test_wcrtomb.c b/tests/test_wcrtomb.c new file mode 100644 index 0000000..e4bc885 --- /dev/null +++ b/tests/test_wcrtomb.c | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main() { | ||
| 6 | char c; | ||
| 7 | wcrtomb(&c, L'0', NULL); | ||
| 8 | return 0; | ||
| 9 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wchar_t src[20]; | ||
| 8 | int i; | ||
| 9 | wcscat(buffer, L"α"); | ||
| 10 | |||
| 11 | for (i = 0; i < argc; i++) | ||
| 12 | src[i] = L'A'; | ||
| 13 | src[i] = L'\0'; | ||
| 14 | |||
| 15 | CHK_FAIL_START | ||
| 16 | wcscat(buffer, src); | ||
| 17 | CHK_FAIL_END | ||
| 18 | |||
| 19 | printf("%ls\n", buffer); | ||
| 20 | return ret; | ||
| 21 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wchar_t src[20]; | ||
| 8 | int i; | ||
| 9 | wcscpy(buffer, L"α"); | ||
| 10 | printf("%ls\n", buffer); | ||
| 11 | |||
| 12 | for (i = 0; i < argc; i++) | ||
| 13 | src[i] = L'A'; | ||
| 14 | src[i] = L'\0'; | ||
| 15 | |||
| 16 | CHK_FAIL_START | ||
| 17 | wcscpy(buffer, src); | ||
| 18 | CHK_FAIL_END | ||
| 19 | |||
| 20 | printf("%ls\n", buffer); | ||
| 21 | return ret; | ||
| 22 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wcsncat(buffer, L"αβγδεζηθικλμνξοπρστυφχψω", 2); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | wcsncat(buffer, L"αβγδεζηθικλμνξοπρστυφχψω", argc + 1336); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | printf("%ls\n", buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
diff --git a/tests/test_wcsncat_n_eq_buf.c b/tests/test_wcsncat_n_eq_buf.c new file mode 100644 index 0000000..e516842 --- /dev/null +++ b/tests/test_wcsncat_n_eq_buf.c | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wcsncat(buffer, L"12345", 5); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | /* n == buffer capacity but overflow due to existing content. | ||
| 11 | * buffer has 5 wchars, src L"ABC" (len 3): 5+3+1 = 9 > 8 → overflow. */ | ||
| 12 | CHK_FAIL_START | ||
| 13 | wcsncat(buffer, L"ABC", 8); | ||
| 14 | CHK_FAIL_END | ||
| 15 | |||
| 16 | printf("%ls\n", buffer); | ||
| 17 | return ret; | ||
| 18 | } | ||
diff --git a/tests/test_wcsncat_n_gt_buf.c b/tests/test_wcsncat_n_gt_buf.c new file mode 100644 index 0000000..186b8c0 --- /dev/null +++ b/tests/test_wcsncat_n_gt_buf.c | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wcsncat(buffer, L"12345", 5); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | /* n > buffer capacity and overflow: n=10, buffer has 5 wchars. */ | ||
| 11 | CHK_FAIL_START | ||
| 12 | wcsncat(buffer, L"1234567890", 10); | ||
| 13 | CHK_FAIL_END | ||
| 14 | |||
| 15 | printf("%ls\n", buffer); | ||
| 16 | return ret; | ||
| 17 | } | ||
diff --git a/tests/test_wcsncat_n_lt_buf.c b/tests/test_wcsncat_n_lt_buf.c new file mode 100644 index 0000000..99a42de --- /dev/null +++ b/tests/test_wcsncat_n_lt_buf.c | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wcsncat(buffer, L"12345", 5); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | /* n < buffer capacity but overflow due to existing content. | ||
| 11 | * buffer has 5 wchars, src L"ABCD" (len 4), min(4,3)=3: 5+3+1 = 9 > 8. */ | ||
| 12 | CHK_FAIL_START | ||
| 13 | wcsncat(buffer, L"ABCD", 3); | ||
| 14 | CHK_FAIL_END | ||
| 15 | |||
| 16 | printf("%ls\n", buffer); | ||
| 17 | return ret; | ||
| 18 | } | ||
diff --git a/tests/test_wcsncat_n_one.c b/tests/test_wcsncat_n_one.c new file mode 100644 index 0000000..23de28e --- /dev/null +++ b/tests/test_wcsncat_n_one.c | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wcsncat(buffer, L"1234567", 7); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | /* n=1, buffer has 7 wchars. | ||
| 11 | * 7+1+1 = 9 > 8 → overflow. Even n=1 can overflow a nearly-full buffer. */ | ||
| 12 | CHK_FAIL_START | ||
| 13 | wcsncat(buffer, L"X", 1); | ||
| 14 | CHK_FAIL_END | ||
| 15 | |||
| 16 | printf("%ls\n", buffer); | ||
| 17 | return ret; | ||
| 18 | } | ||
diff --git a/tests/test_wcsncat_safe.c b/tests/test_wcsncat_safe.c new file mode 100644 index 0000000..00fc8e6 --- /dev/null +++ b/tests/test_wcsncat_safe.c | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | |||
| 8 | /* Safe: empty buffer, append 7 wide chars → exactly fills buffer */ | ||
| 9 | wcsncat(buffer, L"ABCDEFG", 7); | ||
| 10 | printf("%ls\n", buffer); | ||
| 11 | |||
| 12 | /* Safe: reset, append with n larger than source. | ||
| 13 | * src is L"AB" (len 2), n=100 → only 2 wchars copied */ | ||
| 14 | buffer[0] = L'\0'; | ||
| 15 | wcsncat(buffer, L"AB", 100); | ||
| 16 | printf("%ls\n", buffer); | ||
| 17 | |||
| 18 | /* Safe: partially filled, append fits exactly. | ||
| 19 | * buffer = L"ABCD" (4 wchars), append L"EFG" n=3 → 4+3+1 = 8 = exact fit */ | ||
| 20 | buffer[0] = L'\0'; | ||
| 21 | wcsncat(buffer, L"ABCD", 4); | ||
| 22 | wcsncat(buffer, L"EFG", 3); | ||
| 23 | printf("%ls\n", buffer); | ||
| 24 | |||
| 25 | /* Safe: n limits copy to fit. | ||
| 26 | * buffer = L"ABCDE" (5 wchars), src long, n=2 → 5+2+1 = 8 = exact fit */ | ||
| 27 | buffer[0] = L'\0'; | ||
| 28 | wcsncat(buffer, L"ABCDE", 5); | ||
| 29 | wcsncat(buffer, L"FGHIJKLM", 2); | ||
| 30 | printf("%ls\n", buffer); | ||
| 31 | |||
| 32 | /* All safe operations passed without trapping */ | ||
| 33 | return 0; | ||
| 34 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wcsncpy(buffer, L"αβγδεζηθικλμνξοπρστυφχψω", 1); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | wcsncpy(buffer, L"αβγδεζηθικλμνξοπρστυφχψω", argc + 1336); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | printf("%ls\n", buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
diff --git a/tests/test_wcsnrtombs_dynamic.c b/tests/test_wcsnrtombs_dynamic.c new file mode 100644 index 0000000..1637e71 --- /dev/null +++ b/tests/test_wcsnrtombs_dynamic.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | char buffer[8] = {0}; | ||
| 8 | const wchar_t src[] = L"ABCD"; | ||
| 9 | const wchar_t *srcp = src; | ||
| 10 | mbstate_t st; | ||
| 11 | memset(&st, 0, sizeof(st)); | ||
| 12 | |||
| 13 | /* Safe: convert up to 4 wide chars, write at most 4 bytes */ | ||
| 14 | srcp = src; | ||
| 15 | wcsnrtombs(buffer, &srcp, 4, 4, &st); | ||
| 16 | |||
| 17 | /* Unsafe: ask to write argc (10) bytes into 8-byte buffer. */ | ||
| 18 | srcp = src; | ||
| 19 | memset(&st, 0, sizeof(st)); | ||
| 20 | CHK_FAIL_START | ||
| 21 | wcsnrtombs(buffer, &srcp, 4, argc, &st); | ||
| 22 | CHK_FAIL_END | ||
| 23 | |||
| 24 | puts(buffer); | ||
| 25 | return ret; | ||
| 26 | } | ||
diff --git a/tests/test_wcsnrtombs_static.c b/tests/test_wcsnrtombs_static.c new file mode 100644 index 0000000..da529f1 --- /dev/null +++ b/tests/test_wcsnrtombs_static.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | char buffer[4] = {0}; | ||
| 8 | const wchar_t src[] = L"ABCDEFGHIJ"; | ||
| 9 | const wchar_t *srcp = src; | ||
| 10 | mbstate_t st; | ||
| 11 | memset(&st, 0, sizeof(st)); | ||
| 12 | |||
| 13 | /* Safe: convert up to 2 wide chars, write at most 2 bytes */ | ||
| 14 | srcp = src; | ||
| 15 | wcsnrtombs(buffer, &srcp, 2, 2, &st); | ||
| 16 | |||
| 17 | /* Unsafe: ask to write 16 bytes into 4-byte buffer */ | ||
| 18 | srcp = src; | ||
| 19 | memset(&st, 0, sizeof(st)); | ||
| 20 | CHK_FAIL_START | ||
| 21 | wcsnrtombs(buffer, &srcp, 10, 16, &st); | ||
| 22 | CHK_FAIL_END | ||
| 23 | |||
| 24 | puts(buffer); | ||
| 25 | return ret; | ||
| 26 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | char buffer[4] = {0}; | ||
| 8 | const wchar_t src[] = L"ABCDEFGHIJ"; | ||
| 9 | const wchar_t *srcp = src; | ||
| 10 | mbstate_t st; | ||
| 11 | memset(&st, 0, sizeof(st)); | ||
| 12 | |||
| 13 | srcp = src; | ||
| 14 | wcsrtombs(buffer, &srcp, 2, &st); | ||
| 15 | |||
| 16 | srcp = src; | ||
| 17 | memset(&st, 0, sizeof(st)); | ||
| 18 | CHK_FAIL_START | ||
| 19 | wcsrtombs(buffer, &srcp, argc + 15, &st); | ||
| 20 | CHK_FAIL_END | ||
| 21 | |||
| 22 | puts(buffer); | ||
| 23 | return ret; | ||
| 24 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | int main(int argc, char** argv) { | ||
| 7 | char buffer[4] = {0}; | ||
| 8 | const wchar_t src[] = L"ABCDEFGHIJ"; | ||
| 9 | const wchar_t *srcp = src; | ||
| 10 | mbstate_t st; | ||
| 11 | memset(&st, 0, sizeof(st)); | ||
| 12 | |||
| 13 | srcp = src; | ||
| 14 | wcsrtombs(buffer, &srcp, 2, &st); | ||
| 15 | |||
| 16 | srcp = src; | ||
| 17 | memset(&st, 0, sizeof(st)); | ||
| 18 | CHK_FAIL_START | ||
| 19 | wcsrtombs(buffer, &srcp, 16, &st); | ||
| 20 | CHK_FAIL_END | ||
| 21 | |||
| 22 | puts(buffer); | ||
| 23 | return ret; | ||
| 24 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[4] = {0}; | ||
| 7 | |||
| 8 | wcstombs(buffer, L"AB", 2); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | wcstombs(buffer, L"ABCDEFGHIJ", argc + 15); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | puts(buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
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 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | char buffer[4] = {0}; | ||
| 7 | |||
| 8 | wcstombs(buffer, L"AB", 2); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | wcstombs(buffer, L"ABCDEFGHIJ", 16); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | puts(buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
diff --git a/tests/test_wmemcpy_dynamic_read.c b/tests/test_wmemcpy_dynamic_read.c new file mode 100644 index 0000000..20ba0ad --- /dev/null +++ b/tests/test_wmemcpy_dynamic_read.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[12] = {0}; | ||
| 7 | wmemcpy(buffer, L"αβγδεζηθικ", sizeof(buffer) / sizeof(wchar_t) - 1); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | wmemcpy(buffer, L"αβγδεζ", argc); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | printf("%ls\n", buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
diff --git a/tests/test_wmemcpy_static_read.c b/tests/test_wmemcpy_static_read.c new file mode 100644 index 0000000..c87d378 --- /dev/null +++ b/tests/test_wmemcpy_static_read.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wmemcpy(buffer, L"αβγδεζ", 4); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | wmemcpy(buffer, L"αβγδεζ", sizeof(buffer) / sizeof(wchar_t)); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | printf("%ls\n", buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
diff --git a/tests/test_wmemmove_dynamic_read.c b/tests/test_wmemmove_dynamic_read.c new file mode 100644 index 0000000..05e315b --- /dev/null +++ b/tests/test_wmemmove_dynamic_read.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[12] = {0}; | ||
| 7 | wmemmove(buffer, L"αβγδεζηθικ", sizeof(buffer) / sizeof(wchar_t) - 1); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | wmemmove(buffer, L"αβγδεζ", argc); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | printf("%ls\n", buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
diff --git a/tests/test_wmemmove_static_read.c b/tests/test_wmemmove_static_read.c new file mode 100644 index 0000000..6e4a929 --- /dev/null +++ b/tests/test_wmemmove_static_read.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <wchar.h> | ||
| 4 | |||
| 5 | int main(int argc, char** argv) { | ||
| 6 | wchar_t buffer[8] = {0}; | ||
| 7 | wmemmove(buffer, L"αβγδεζ", 4); | ||
| 8 | printf("%ls\n", buffer); | ||
| 9 | |||
| 10 | CHK_FAIL_START | ||
| 11 | wmemmove(buffer, L"αβγδεζ", sizeof(buffer) / sizeof(wchar_t)); | ||
| 12 | CHK_FAIL_END | ||
| 13 | |||
| 14 | printf("%ls\n", buffer); | ||
| 15 | return ret; | ||
| 16 | } | ||
