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: 1}]}" \
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