1 | // RUN: %check_clang_tidy %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 | |