1 // RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
2 // RUN: -config="{CheckOptions: \
3 // RUN: [{key: bugprone-not-null-terminated-result.WantToUseSafeFunctions, \
4 // RUN:   value: true}]}" \
5 // RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
6 
7 #include "not-null-terminated-result-c.h"
8 
9 // The following is not defined therefore the safe functions are unavailable.
10 // #define __STDC_LIB_EXT1__ 1
11 
12 #define __STDC_WANT_LIB_EXT1__ 1
13 
14 //===----------------------------------------------------------------------===//
15 // memcpy() - destination array tests
16 //===----------------------------------------------------------------------===//
17 
bad_memcpy_not_just_char_dest(const char * src)18 void bad_memcpy_not_just_char_dest(const char *src) {
19   unsigned char dest00[13];
20   memcpy(dest00, src, strlen(src));
21   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
22   // CHECK-FIXES: unsigned char dest00[14];
23   // CHECK-FIXES-NEXT: strcpy((char *)dest00, src);
24 }
25 
good_memcpy_not_just_char_dest(const char * src)26 void good_memcpy_not_just_char_dest(const char *src) {
27   unsigned char dst00[14];
28   strcpy((char *)dst00, src);
29 }
30 
bad_memcpy_known_dest(const char * src)31 void bad_memcpy_known_dest(const char *src) {
32   char dest01[13];
33   memcpy(dest01, src, strlen(src));
34   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
35   // CHECK-FIXES: strcpy(dest01, src);
36 }
37 
good_memcpy_known_dest(const char * src)38 void good_memcpy_known_dest(const char *src) {
39   char dst01[13];
40   strcpy(dst01, src);
41 }
42 
43 //===----------------------------------------------------------------------===//
44 // memcpy() - length tests
45 //===----------------------------------------------------------------------===//
46 
bad_memcpy_full_source_length(const char * src)47 void bad_memcpy_full_source_length(const char *src) {
48   char dest20[13];
49   memcpy(dest20, src, strlen(src));
50   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
51   // CHECK-FIXES: strcpy(dest20, src);
52 }
53 
good_memcpy_full_source_length(const char * src)54 void good_memcpy_full_source_length(const char *src) {
55   char dst20[13];
56   strcpy(dst20, src);
57 }
58 
bad_memcpy_partial_source_length(const char * src)59 void bad_memcpy_partial_source_length(const char *src) {
60   char dest21[13];
61   memcpy(dest21, src, strlen(src) - 1);
62   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
63   // CHECK-FIXES: strncpy(dest21, src, strlen(src) - 1);
64   // CHECK-FIXES-NEXT: dest21[strlen(src) - 1] = '\0';
65 }
66 
good_memcpy_partial_source_length(const char * src)67 void good_memcpy_partial_source_length(const char *src) {
68   char dst21[13];
69   strncpy(dst21, src, strlen(src) - 1);
70   dst21[strlen(src) - 1] = '\0';
71 }
72