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