1 // RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
2 // RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
3 
4 #include "not-null-terminated-result-c.h"
5 
6 #define __STDC_LIB_EXT1__ 1
7 #define __STDC_WANT_LIB_EXT1__ 1
8 
9 #define SRC_LENGTH 3
10 #define SRC "foo"
11 
12 //===----------------------------------------------------------------------===//
13 // False positive suppression.
14 //===----------------------------------------------------------------------===//
15 
good_memcpy_known_src()16 void good_memcpy_known_src() {
17   char dest[13];
18   char src[] = "foobar";
19   memcpy(dest, src, sizeof(src));
20 }
21 
good_memcpy_null_terminated(const char * src)22 void good_memcpy_null_terminated(const char *src) {
23   char dest[13];
24   const int length = strlen(src);
25   memcpy(dest, src, length);
26   dest[length] = '\0';
27 }
28 
good_memcpy_proper_length(const char * src)29 void good_memcpy_proper_length(const char *src) {
30   char *dest = 0;
31   int length = strlen(src) + 1;
32   dest = (char *)malloc(length);
33   memcpy(dest, src, length);
34 }
35 
may_bad_memcpy_unknown_length(const char * src,int length)36 void may_bad_memcpy_unknown_length(const char *src, int length) {
37   char dest[13];
38   memcpy(dest, src, length);
39 }
40 
may_bad_memcpy_const_length(const char * src)41 void may_bad_memcpy_const_length(const char *src) {
42   char dest[13];
43   memcpy(dest, src, 12);
44 }
45 
46 //===----------------------------------------------------------------------===//
47 // Special cases.
48 //===----------------------------------------------------------------------===//
49 
bad_memcpy_unknown_dest(char * dest01,const char * src)50 void bad_memcpy_unknown_dest(char *dest01, const char *src) {
51   memcpy(dest01, src, strlen(src));
52   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
53   // CHECK-FIXES: strcpy(dest01, src);
54 }
55 
good_memcpy_unknown_dest(char * dst01,const char * src)56 void good_memcpy_unknown_dest(char *dst01, const char *src) {
57   strcpy(dst01, src);
58 }
59 
bad_memcpy_variable_array(int dest_length)60 void bad_memcpy_variable_array(int dest_length) {
61   char dest02[dest_length + 1];
62   memcpy(dest02, "foobarbazqux", strlen("foobarbazqux"));
63   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
64   // CHECK-FIXES: strcpy(dest02, "foobarbazqux");
65 }
66 
good_memcpy_variable_array(int dest_length)67 void good_memcpy_variable_array(int dest_length) {
68   char dst02[dest_length + 1];
69   strcpy(dst02, "foobarbazqux");
70 }
71 
bad_memcpy_equal_src_length_and_length()72 void bad_memcpy_equal_src_length_and_length() {
73   char dest03[13];
74   const char *src = "foobarbazqux";
75   memcpy(dest03, src, 12);
76   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
77   // CHECK-FIXES: strcpy(dest03, src);
78 }
79 
good_memcpy_equal_src_length_and_length()80 void good_memcpy_equal_src_length_and_length() {
81   char dst03[13];
82   const char *src = "foobarbazqux";
83   strcpy(dst03, src);
84 }
85 
bad_memcpy_dest_size_overflows(const char * src)86 void bad_memcpy_dest_size_overflows(const char *src) {
87   const int length = strlen(src);
88   char *dest04 = (char *)malloc(length);
89   memcpy(dest04, src, length);
90   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
91   // CHECK-FIXES: char *dest04 = (char *)malloc(length + 1);
92   // CHECK-FIXES-NEXT: strcpy(dest04, src);
93 }
94 
good_memcpy_dest_size_overflows(const char * src)95 void good_memcpy_dest_size_overflows(const char *src) {
96   const int length = strlen(src);
97   char *dst04 = (char *)malloc(length + 1);
98   strcpy(dst04, src);
99 }
100 
bad_memcpy_macro()101 void bad_memcpy_macro() {
102   char dest05[SRC_LENGTH];
103   memcpy(dest05, SRC, SRC_LENGTH);
104   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
105   // CHECK-FIXES: char dest05[SRC_LENGTH + 1];
106   // CHECK-FIXES-NEXT: strcpy(dest05, SRC);
107 }
108 
good_memcpy_macro()109 void good_memcpy_macro() {
110   char dst05[SRC_LENGTH + 1];
111   strcpy(dst05, SRC);
112 }
113