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
14void 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
20void good_wmemchr_1(wchar_t *pos, const wchar_t *src) {
21 pos = wcschr(src, L'\0');
22}
23
24void 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
30void good_wmemchr_2(wchar_t *pos) {
31 pos = wcschr(L"foobar", L'\0');
32}
33
34
35void 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
43void good_wmemmove(const wchar_t *src) {
44 wchar_t dst[14];
45 wmemmove_s(dst, 13, src, wcslen(src) + 1);
46}
47
48void 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
54void good_wmemmove_s_1(wchar_t *dest, const wchar_t *src) {
55 wmemmove_s(dest, 13, src, wcslen(src) + 1);
56}
57
58int 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
64int 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
70int good_wcsncmp_1_2(wchar_t *wcs4, const wchar_t *wcs5) {
71 return wcsncmp(wcs4, wcs5, wcslen(wcs4));
72}
73
74int 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
80int good_wcsncmp_3(wchar_t *wcs7) {
81 return wcsncmp(wcs7, L"string", 6);
82}
83
84void 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
94void 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
100void 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
108void good_wcsxfrm_2() {
109 wchar_t long_destination_array_name2[17];
110 wcsxfrm(long_destination_array_name2, L"long_source_name", 17);
111}
112

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp