| 1 | // RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \ |
| 2 | // RUN: -- -std=c++11 -I %S/Inputs/not-null-terminated-result |
| 3 | |
| 4 | // FIXME: Something wrong with the APInt un/signed conversion on Windows: |
| 5 | // in 'wcsncmp(wcs6, L"string", 7);' it tries to inject '4294967302' as length. |
| 6 | |
| 7 | // UNSUPPORTED: system-windows |
| 8 | |
| 9 | #include "not-null-terminated-result-cxx.h" |
| 10 | |
| 11 | #define __STDC_LIB_EXT1__ 1 |
| 12 | #define __STDC_WANT_LIB_EXT1__ 1 |
| 13 | |
| 14 | void bad_wmemchr_1(wchar_t *position, const wchar_t *src) { |
| 15 | position = (wchar_t *)wmemchr(src, L'\0', wcslen(src)); |
| 16 | // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: the length is too short to include the null terminator [bugprone-not-null-terminated-result] |
| 17 | // CHECK-FIXES: position = wcschr(src, L'\0'); |
| 18 | } |
| 19 | |
| 20 | void good_wmemchr_1(wchar_t *pos, const wchar_t *src) { |
| 21 | pos = wcschr(src, L'\0'); |
| 22 | } |
| 23 | |
| 24 | void bad_wmemchr_2(wchar_t *position) { |
| 25 | position = (wchar_t *)wmemchr(L"foobar" , L'\0', 6); |
| 26 | // CHECK-MESSAGES: :[[@LINE-1]]:51: warning: the length is too short to include the null terminator [bugprone-not-null-terminated-result] |
| 27 | // CHECK-FIXES: position = wcschr(L"foobar", L'\0'); |
| 28 | } |
| 29 | |
| 30 | void good_wmemchr_2(wchar_t *pos) { |
| 31 | pos = wcschr(L"foobar" , L'\0'); |
| 32 | } |
| 33 | |
| 34 | |
| 35 | void bad_wmemmove(const wchar_t *src) { |
| 36 | wchar_t dest[13]; |
| 37 | wmemmove(dest, src, wcslen(src)); |
| 38 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'wmemmove' is not null-terminated [bugprone-not-null-terminated-result] |
| 39 | // CHECK-FIXES: wchar_t dest[14]; |
| 40 | // CHECK-FIXES-NEXT: wmemmove_s(dest, 14, src, wcslen(src) + 1); |
| 41 | } |
| 42 | |
| 43 | void good_wmemmove(const wchar_t *src) { |
| 44 | wchar_t dst[14]; |
| 45 | wmemmove_s(dst, 13, src, wcslen(src) + 1); |
| 46 | } |
| 47 | |
| 48 | void bad_wmemmove_s(wchar_t *dest, const wchar_t *src) { |
| 49 | wmemmove_s(dest, 13, src, wcslen(src)); |
| 50 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'wmemmove_s' is not null-terminated [bugprone-not-null-terminated-result] |
| 51 | // CHECK-FIXES: wmemmove_s(dest, 13, src, wcslen(src) + 1); |
| 52 | } |
| 53 | |
| 54 | void good_wmemmove_s_1(wchar_t *dest, const wchar_t *src) { |
| 55 | wmemmove_s(dest, 13, src, wcslen(src) + 1); |
| 56 | } |
| 57 | |
| 58 | int bad_wcsncmp_1(wchar_t *wcs0, const wchar_t *wcs1) { |
| 59 | return wcsncmp(wcs0, wcs1, (wcslen(wcs0) + 1)); |
| 60 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] |
| 61 | // CHECK-FIXES: wcsncmp(wcs0, wcs1, (wcslen(wcs0))); |
| 62 | } |
| 63 | |
| 64 | int bad_wcsncmp_2(wchar_t *wcs2, const wchar_t *wcs3) { |
| 65 | return wcsncmp(wcs2, wcs3, 1 + wcslen(wcs2)); |
| 66 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] |
| 67 | // CHECK-FIXES: wcsncmp(wcs2, wcs3, wcslen(wcs2)); |
| 68 | } |
| 69 | |
| 70 | int good_wcsncmp_1_2(wchar_t *wcs4, const wchar_t *wcs5) { |
| 71 | return wcsncmp(wcs4, wcs5, wcslen(wcs4)); |
| 72 | } |
| 73 | |
| 74 | int bad_wcsncmp_3(wchar_t *wcs6) { |
| 75 | return wcsncmp(wcs6, L"string" , 7); |
| 76 | // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] |
| 77 | // CHECK-FIXES: wcsncmp(wcs6, L"string", 6); |
| 78 | } |
| 79 | |
| 80 | int good_wcsncmp_3(wchar_t *wcs7) { |
| 81 | return wcsncmp(wcs7, L"string" , 6); |
| 82 | } |
| 83 | |
| 84 | void bad_wcsxfrm_1(const wchar_t *long_source_name) { |
| 85 | wchar_t long_destination_array_name[13]; |
| 86 | wcsxfrm(long_destination_array_name, long_source_name, |
| 87 | wcslen(long_source_name)); |
| 88 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the result from calling 'wcsxfrm' is not null-terminated [bugprone-not-null-terminated-result] |
| 89 | // CHECK-FIXES: wchar_t long_destination_array_name[14]; |
| 90 | // CHECK-FIXES-NEXT: wcsxfrm(long_destination_array_name, long_source_name, |
| 91 | // CHECK-FIXES-NEXT: wcslen(long_source_name) + 1); |
| 92 | } |
| 93 | |
| 94 | void good_wcsxfrm_1(const wchar_t *long_source_name) { |
| 95 | wchar_t long_destination_array_name[14]; |
| 96 | wcsxfrm(long_destination_array_name, long_source_name, |
| 97 | wcslen(long_source_name) + 1); |
| 98 | } |
| 99 | |
| 100 | void bad_wcsxfrm_2() { |
| 101 | wchar_t long_destination_array_name1[16]; |
| 102 | wcsxfrm(long_destination_array_name1, L"long_source_name" , 16); |
| 103 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'wcsxfrm' is not null-terminated [bugprone-not-null-terminated-result] |
| 104 | // CHECK-FIXES: wchar_t long_destination_array_name1[17]; |
| 105 | // CHECK-FIXES: wcsxfrm(long_destination_array_name1, L"long_source_name", 17); |
| 106 | } |
| 107 | |
| 108 | void good_wcsxfrm_2() { |
| 109 | wchar_t long_destination_array_name2[17]; |
| 110 | wcsxfrm(long_destination_array_name2, L"long_source_name" , 17); |
| 111 | } |
| 112 | |