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