1 // RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
2 // RUN: -- -std=c++11 -I %S/Inputs/bugprone-not-null-terminated-result
3 
4 #include "not-null-terminated-result-cxx.h"
5 
6 #define __STDC_LIB_EXT1__ 1
7 #define __STDC_WANT_LIB_EXT1__ 1
8 
9 //===----------------------------------------------------------------------===//
10 // memcpy() - destination array tests
11 //===----------------------------------------------------------------------===//
12 
bad_memcpy_not_just_char_dest(const char * src)13 void bad_memcpy_not_just_char_dest(const char *src) {
14   unsigned char dest00[13];
15   memcpy(dest00, src, strlen(src));
16   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
17   // CHECK-FIXES: unsigned char dest00[14];
18   // CHECK-FIXES-NEXT: strcpy_s((char *)dest00, 14, src);
19 }
20 
good_memcpy_not_just_char_dest(const char * src)21 void good_memcpy_not_just_char_dest(const char *src) {
22   unsigned char dst00[14];
23   strcpy_s((char *)dst00, 14, src);
24 }
25 
bad_memcpy_known_dest(const char * src)26 void bad_memcpy_known_dest(const char *src) {
27   char dest01[13];
28   memcpy(dest01, src, strlen(src));
29   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
30   // CHECK-FIXES: dest01[14];
31   // CHECK-FIXES-NEXT: strcpy_s(dest01, src);
32 }
33 
good_memcpy_known_dest(const char * src)34 void good_memcpy_known_dest(const char *src) {
35   char dst01[14];
36   strcpy_s(dst01, src);
37 }
38 
39 //===----------------------------------------------------------------------===//
40 // memcpy() - length tests
41 //===----------------------------------------------------------------------===//
42 
bad_memcpy_full_source_length(std::string src)43 void bad_memcpy_full_source_length(std::string src) {
44   char *dest20 = reinterpret_cast<char *>(malloc(src.size()));
45   memcpy(dest20, src.data(), src.size());
46   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
47   // CHECK-FIXES: dest20 = reinterpret_cast<char *>(malloc(src.size() + 1));
48   // CHECK-FIXES-NEXT: strcpy(dest20, src.data());
49 }
50 
good_memcpy_full_source_length(std::string src)51 void good_memcpy_full_source_length(std::string src) {
52   char dst20[14];
53   strcpy_s(dst20, src.data());
54 }
55 
bad_memcpy_partial_source_length(const char * src)56 void bad_memcpy_partial_source_length(const char *src) {
57   char dest21[13];
58   memcpy(dest21, src, strlen(src) - 1);
59   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
60   // CHECK-FIXES: char dest21[14];
61   // CHECK-FIXES-NEXT: strncpy_s(dest21, src, strlen(src) - 1);
62 }
63 
good_memcpy_partial_source_length(const char * src)64 void good_memcpy_partial_source_length(const char *src) {
65   char dst21[14];
66   strncpy_s(dst21, src, strlen(src) - 1);
67 }
68 
69 //===----------------------------------------------------------------------===//
70 // memcpy_s() - destination array tests
71 //===----------------------------------------------------------------------===//
72 
bad_memcpy_s_unknown_dest(char * dest40,const char * src)73 void bad_memcpy_s_unknown_dest(char *dest40, const char *src) {
74   memcpy_s(dest40, 13, src, strlen(src));
75   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
76   // CHECK-FIXES: strcpy_s(dest40, 13, src);
77 }
78 
good_memcpy_s_unknown_dest(char * dst40,const char * src)79 void good_memcpy_s_unknown_dest(char *dst40, const char *src) {
80   strcpy_s(dst40, 13, src);
81 }
82 
bad_memcpy_s_known_dest(const char * src)83 void bad_memcpy_s_known_dest(const char *src) {
84   char dest41[13];
85   memcpy_s(dest41, 13, src, strlen(src));
86   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
87   // CHECK-FIXES: char dest41[14];
88   // CHECK-FIXES: strcpy_s(dest41, src);
89 }
90 
good_memcpy_s_known_dest(const char * src)91 void good_memcpy_s_known_dest(const char *src) {
92   char dst41[14];
93   strcpy_s(dst41, src);
94 }
95 
96 //===----------------------------------------------------------------------===//
97 // memcpy_s() - length tests
98 //===----------------------------------------------------------------------===//
99 
bad_memcpy_s_full_source_length(const char * src)100 void bad_memcpy_s_full_source_length(const char *src) {
101   char dest60[13];
102   memcpy_s(dest60, 13, src, strlen(src));
103   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
104   // CHECK-FIXES: char dest60[14];
105   // CHECK-FIXES-NEXT: strcpy_s(dest60, src);
106 }
107 
good_memcpy_s_full_source_length(const char * src)108 void good_memcpy_s_full_source_length(const char *src) {
109   char dst60[14];
110   strcpy_s(dst60, src);
111 }
112 
bad_memcpy_s_partial_source_length(const char * src)113 void bad_memcpy_s_partial_source_length(const char *src) {
114   char dest61[13];
115   memcpy_s(dest61, 13, src, strlen(src) - 1);
116   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
117   // CHECK-FIXES: char dest61[14];
118   // CHECK-FIXES-NEXT: strncpy_s(dest61, src, strlen(src) - 1);
119 }
120 
good_memcpy_s_partial_source_length(const char * src)121 void good_memcpy_s_partial_source_length(const char *src) {
122   char dst61[14];
123   strncpy_s(dst61, src, strlen(src) - 1);
124 }
125