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